add ABI compatibility check

minor revision shouldn't matter, we only check major revision number.
Bumped all version numbers so that incompatibility starts *now*

Change-Id: Id06c20f03039845ae4cfb3fd121807b931d67ee4
This commit is contained in:
Pascal Massimino 2012-07-18 11:53:25 -07:00
parent 2a77557002
commit f7f16a2976
9 changed files with 30 additions and 21 deletions

View File

@ -35,9 +35,10 @@ static void SetOk(VP8Decoder* const dec) {
} }
int VP8InitIoInternal(VP8Io* const io, int version) { int VP8InitIoInternal(VP8Io* const io, int version) {
if (version != WEBP_DECODER_ABI_VERSION) if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
return 0; // mismatch error return 0; // mismatch error
if (io) { }
if (io != NULL) {
memset(io, 0, sizeof(*io)); memset(io, 0, sizeof(*io));
} }
return 1; return 1;
@ -45,7 +46,7 @@ int VP8InitIoInternal(VP8Io* const io, int version) {
VP8Decoder* VP8New(void) { VP8Decoder* VP8New(void) {
VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(VP8Decoder)); VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(VP8Decoder));
if (dec) { if (dec != NULL) {
SetOk(dec); SetOk(dec);
WebPWorkerInit(&dec->worker_); WebPWorkerInit(&dec->worker_);
dec->ready_ = 0; dec->ready_ = 0;
@ -60,13 +61,13 @@ VP8StatusCode VP8Status(VP8Decoder* const dec) {
} }
const char* VP8StatusMessage(VP8Decoder* const dec) { const char* VP8StatusMessage(VP8Decoder* const dec) {
if (!dec) return "no object"; if (dec == NULL) return "no object";
if (!dec->error_msg_) return "OK"; if (!dec->error_msg_) return "OK";
return dec->error_msg_; return dec->error_msg_;
} }
void VP8Delete(VP8Decoder* const dec) { void VP8Delete(VP8Decoder* const dec) {
if (dec) { if (dec != NULL) {
VP8Clear(dec); VP8Clear(dec);
free(dec); free(dec);
} }
@ -136,7 +137,7 @@ int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
// Header parsing // Header parsing
static void ResetSegmentHeader(VP8SegmentHeader* const hdr) { static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
assert(hdr); assert(hdr != NULL);
hdr->use_segment_ = 0; hdr->use_segment_ = 0;
hdr->update_map_ = 0; hdr->update_map_ = 0;
hdr->absolute_delta_ = 1; hdr->absolute_delta_ = 1;
@ -147,8 +148,8 @@ static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
// Paragraph 9.3 // Paragraph 9.3
static int ParseSegmentHeader(VP8BitReader* br, static int ParseSegmentHeader(VP8BitReader* br,
VP8SegmentHeader* hdr, VP8Proba* proba) { VP8SegmentHeader* hdr, VP8Proba* proba) {
assert(br); assert(br != NULL);
assert(hdr); assert(hdr != NULL);
hdr->use_segment_ = VP8Get(br); hdr->use_segment_ = VP8Get(br);
if (hdr->use_segment_) { if (hdr->use_segment_) {
hdr->update_map_ = VP8Get(br); hdr->update_map_ = VP8Get(br);

View File

@ -651,7 +651,7 @@ int WebPGetInfo(const uint8_t* data, size_t data_size,
int WebPInitDecoderConfigInternal(WebPDecoderConfig* config, int WebPInitDecoderConfigInternal(WebPDecoderConfig* config,
int version) { int version) {
if (version != WEBP_DECODER_ABI_VERSION) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
return 0; // version mismatch return 0; // version mismatch
} }
if (config == NULL) { if (config == NULL) {
@ -667,7 +667,7 @@ VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
WebPBitstreamFeatures* features, WebPBitstreamFeatures* features,
int version) { int version) {
VP8StatusCode status; VP8StatusCode status;
if (version != WEBP_DECODER_ABI_VERSION) { if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
return VP8_STATUS_INVALID_PARAM; // version mismatch return VP8_STATUS_INVALID_PARAM; // version mismatch
} }
if (features == NULL) { if (features == NULL) {

View File

@ -631,7 +631,7 @@ WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
MemBuffer mem; MemBuffer mem;
WebPDemuxer* dmux; WebPDemuxer* dmux;
if (version != WEBP_DEMUX_ABI_VERSION) return NULL; if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DEMUX_ABI_VERSION)) return NULL;
if (data == NULL || data->bytes_ == NULL || data->size_ == 0) return NULL; if (data == NULL || data->bytes_ == NULL || data->size_ == 0) return NULL;
if (!InitMemBuffer(&mem, data->bytes_, data->size_)) return NULL; if (!InitMemBuffer(&mem, data->bytes_, data->size_)) return NULL;

View File

@ -35,12 +35,15 @@ static void MuxInit(WebPMux* const mux) {
} }
WebPMux* WebPNewInternal(int version) { WebPMux* WebPNewInternal(int version) {
WebPMux* const mux = (version == WEBP_MUX_ABI_VERSION) ? if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
(WebPMux*)malloc(sizeof(WebPMux)) : NULL; return NULL;
} else {
WebPMux* const mux = (WebPMux*)malloc(sizeof(WebPMux));
// If mux is NULL MuxInit is a noop. // If mux is NULL MuxInit is a noop.
MuxInit(mux); MuxInit(mux);
return mux; return mux;
} }
}
static void DeleteAllChunks(WebPChunk** const chunk_list) { static void DeleteAllChunks(WebPChunk** const chunk_list) {
while (*chunk_list) { while (*chunk_list) {

View File

@ -89,7 +89,9 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
ChunkInit(&chunk); ChunkInit(&chunk);
// Sanity checks. // Sanity checks.
if (version != WEBP_MUX_ABI_VERSION) return NULL; // version mismatch if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
return NULL; // version mismatch
}
if (bitstream == NULL) return NULL; if (bitstream == NULL) return NULL;
data = bitstream->bytes_; data = bitstream->bytes_;

View File

@ -18,7 +18,7 @@
extern "C" { extern "C" {
#endif #endif
#define WEBP_DECODER_ABI_VERSION 0x0003 #define WEBP_DECODER_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
// Return the decoder's version number, packed in hexadecimal using 8bits for // Return the decoder's version number, packed in hexadecimal using 8bits for
// each of major/minor/revision. E.g: v2.5.7 is 0x020507. // each of major/minor/revision. E.g: v2.5.7 is 0x020507.

View File

@ -18,7 +18,7 @@
extern "C" { extern "C" {
#endif #endif
#define WEBP_ENCODER_ABI_VERSION 0x0003 #define WEBP_ENCODER_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
// Return the encoder's version number, packed in hexadecimal using 8bits for // Return the encoder's version number, packed in hexadecimal using 8bits for
// each of major/minor/revision. E.g: v2.5.7 is 0x020507. // each of major/minor/revision. E.g: v2.5.7 is 0x020507.

View File

@ -51,7 +51,7 @@
extern "C" { extern "C" {
#endif #endif
#define WEBP_MUX_ABI_VERSION 0x0000 #define WEBP_MUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
// Error codes // Error codes
typedef enum { typedef enum {
@ -461,7 +461,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux,
// Demux API. // Demux API.
// Enables extraction of image and extended format data from WebP files. // Enables extraction of image and extended format data from WebP files.
#define WEBP_DEMUX_ABI_VERSION 0x0000 #define WEBP_DEMUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b)
typedef struct WebPDemuxer WebPDemuxer; typedef struct WebPDemuxer WebPDemuxer;

View File

@ -39,4 +39,7 @@ typedef long long int int64_t;
#define WEBP_EXTERN(type) extern type #define WEBP_EXTERN(type) extern type
#endif /* WEBP_EXTERN */ #endif /* WEBP_EXTERN */
// Macro to check ABI compatibility (same major revision number)
#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8))
#endif /* WEBP_WEBP_TYPES_H_ */ #endif /* WEBP_WEBP_TYPES_H_ */