diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 8d91c295e..38d013f31 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -707,7 +707,8 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name) */ if (!name) return NULL; - + memset(tokens, 0, sizeof(tokens)); + length = strlen(name); if (length < 10) @@ -753,7 +754,7 @@ char* PCSC_ConvertReaderNameToWinSCard(const char* name) if ((index < 0) || (slot < 0)) return NULL; - if (*(tokens[ctoken][1] - 1) == ')') + if (tokens[ctoken] && tokens[ctoken][1] && *(tokens[ctoken][1] - 1) == ')') { while ((*(tokens[ctoken][0]) != '(') && (ctoken > 0)) ctoken--; @@ -2358,7 +2359,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dw WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) { int length = 0; - char* namePCSC; + char* namePCSC = NULL; char* nameWinSCard; DWORD cbAttrLen = 0; char* pbAttrA = NULL; @@ -2414,6 +2415,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWOR else { friendlyNameA = namePCSC; + namePCSC = NULL; } if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) diff --git a/winpr/libwinpr/utils/image.c b/winpr/libwinpr/utils/image.c index 62b2cb0e1..d6c5a0f6e 100644 --- a/winpr/libwinpr/utils/image.c +++ b/winpr/libwinpr/utils/image.c @@ -192,7 +192,7 @@ int winpr_image_bitmap_read_fp(wImage* image, FILE* fp) image->bitsPerPixel = bi.biBitCount; image->bytesPerPixel = (image->bitsPerPixel / 8); - image->scanline = (bi.biSizeImage / bi.biHeight); + image->scanline = (bi.biSizeImage / image->height); image->data = (BYTE*) malloc(bi.biSizeImage); @@ -261,7 +261,7 @@ int winpr_image_bitmap_read_buffer(wImage* image, BYTE* buffer, int size) image->bitsPerPixel = bi.biBitCount; image->bytesPerPixel = (image->bitsPerPixel / 8); - image->scanline = (bi.biSizeImage / bi.biHeight); + image->scanline = (bi.biSizeImage / image->height); image->data = (BYTE*) malloc(bi.biSizeImage); diff --git a/winpr/libwinpr/utils/ini.c b/winpr/libwinpr/utils/ini.c index f6d043ac0..f46e41d7b 100644 --- a/winpr/libwinpr/utils/ini.c +++ b/winpr/libwinpr/utils/ini.c @@ -376,7 +376,9 @@ int IniFile_Load(wIniFile* ini) value = beg; IniFile_AddKey(ini, section, name, value); - key = section->keys[section->nKeys - 1]; + key = NULL; + if (section && section->keys) + key = section->keys[section->nKeys - 1]; } } diff --git a/winpr/libwinpr/utils/lodepng/lodepng.c b/winpr/libwinpr/utils/lodepng/lodepng.c index a65926c41..3f6a73022 100644 --- a/winpr/libwinpr/utils/lodepng/lodepng.c +++ b/winpr/libwinpr/utils/lodepng/lodepng.c @@ -22,6 +22,8 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +/* Copyright (c) 2015 Armin Novak + * Modifications fixing various errors. */ #include "lodepng.h" @@ -117,7 +119,11 @@ static unsigned uivector_reserve(uivector* p, size_t allocsize) p->allocsize = newsize; p->data = (unsigned*)data; } - else return 0; /*error: not enough memory*/ + else + { + uivector_cleanup(p); + return 0; /*error: not enough memory*/ + } } return 1; } @@ -175,6 +181,13 @@ typedef struct ucvector size_t allocsize; /*allocated size*/ } ucvector; +static void ucvector_cleanup(void* p) +{ + ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; + free(((ucvector*)p)->data); + ((ucvector*)p)->data = NULL; +} + /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_reserve(ucvector* p, size_t allocsize) { @@ -187,7 +200,11 @@ static unsigned ucvector_reserve(ucvector* p, size_t allocsize) p->allocsize = newsize; p->data = (unsigned char*)data; } - else return 0; /*error: not enough memory*/ + else + { + ucvector_cleanup(p); + return 0; /*error: not enough memory*/ + } } return 1; } @@ -202,13 +219,6 @@ static unsigned ucvector_resize(ucvector* p, size_t size) #ifdef LODEPNG_COMPILE_PNG -static void ucvector_cleanup(void* p) -{ - ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; - free(((ucvector*)p)->data); - ((ucvector*)p)->data = NULL; -} - static void ucvector_init(ucvector* p) { p->data = NULL; @@ -252,6 +262,14 @@ static unsigned ucvector_push_back(ucvector* p, unsigned char c) #ifdef LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +/*free the above pair again*/ +static void string_cleanup(char** out) +{ + free(*out); + *out = NULL; +} + /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned string_resize(char** out, size_t size) { @@ -261,6 +279,9 @@ static unsigned string_resize(char** out, size_t size) data[size] = 0; /*null termination char*/ *out = data; } + else + string_cleanup(out); + return data != 0; } @@ -271,13 +292,6 @@ static void string_init(char** out) string_resize(out, 0); } -/*free the above pair again*/ -static void string_cleanup(char** out) -{ - free(*out); - *out = NULL; -} - static void string_set(char** out, const char* in) { size_t insize = strlen(in), i = 0; @@ -311,10 +325,11 @@ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ #ifdef LODEPNG_COMPILE_ENCODER -static void lodepng_add32bitInt(ucvector* buffer, unsigned value) +static int lodepng_add32bitInt(ucvector* buffer, unsigned value) { - ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ + if (!ucvector_resize(buffer, buffer->size + 4)) return 0; lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); + return 1; } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -373,13 +388,19 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_ENCODER /*TODO: this ignores potential out of memory errors*/ -#define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\ -{\ - /*add a new byte at the end*/\ - if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ - /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ - (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ - (*bitpointer)++;\ +static int addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit) +{ + /*add a new byte at the end*/ + if(((*bitpointer) & 7) == 0) + { + if (!ucvector_push_back(bitstream, (unsigned char)0)) return 83; + } + + /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ + (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); + (*bitpointer)++; + + return 0; } static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) @@ -488,6 +509,8 @@ static void HuffmanTree_init(HuffmanTree* tree) tree->tree2d = 0; tree->tree1d = 0; tree->lengths = 0; + tree->maxbitlen = 0; + tree->numcodes = 0; } static void HuffmanTree_cleanup(HuffmanTree* tree) @@ -504,7 +527,7 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ unsigned n, i; - tree->tree2d = (unsigned*)malloc(tree->numcodes * 2 * sizeof(unsigned)); + tree->tree2d = (unsigned*)calloc(tree->numcodes * 2, sizeof(unsigned)); if(!tree->tree2d) return 83; /*alloc fail*/ /* @@ -571,7 +594,7 @@ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) uivector_init(&blcount); uivector_init(&nextcode); - tree->tree1d = (unsigned*)malloc(tree->numcodes * sizeof(unsigned)); + tree->tree1d = (unsigned*)calloc(tree->numcodes, sizeof(unsigned)); if(!tree->tree1d) error = 83; /*alloc fail*/ if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) @@ -610,7 +633,7 @@ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* b size_t numcodes, unsigned maxbitlen) { unsigned i; - tree->lengths = (unsigned*)malloc(numcodes * sizeof(unsigned)); + tree->lengths = (unsigned*)calloc(numcodes, sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ for(i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i]; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ @@ -841,7 +864,7 @@ static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) static unsigned generateFixedLitLenTree(HuffmanTree* tree) { unsigned i, error = 0; - unsigned* bitlen = (unsigned*)malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + unsigned* bitlen = (unsigned*)calloc(NUM_DEFLATE_CODE_SYMBOLS, sizeof(unsigned)); if(!bitlen) return 83; /*alloc fail*/ /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ @@ -905,11 +928,13 @@ static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, /* ////////////////////////////////////////////////////////////////////////// */ /*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ -static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) +static int getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { - /*TODO: check for out of memory errors*/ - generateFixedLitLenTree(tree_ll); - generateFixedDistanceTree(tree_d); + int rc; + + rc = generateFixedLitLenTree(tree_ll); + if (rc) return rc; + return generateFixedDistanceTree(tree_d); } /*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ @@ -1072,7 +1097,16 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); - if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); + if(btype == 1) + { + error = getTreeInflateFixed(&tree_ll, &tree_d); + if (error) + { + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + return error; + } + } else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); while(!error) /*decode all symbols until end reached, breaks at end code*/ @@ -1598,21 +1632,21 @@ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, s BTYPE = 0; firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); - ucvector_push_back(out, firstbyte); + if (!ucvector_push_back(out, firstbyte)) return 83; LEN = 65535; if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; NLEN = 65535 - LEN; - ucvector_push_back(out, (unsigned char)(LEN % 256)); - ucvector_push_back(out, (unsigned char)(LEN / 256)); - ucvector_push_back(out, (unsigned char)(NLEN % 256)); - ucvector_push_back(out, (unsigned char)(NLEN / 256)); + if (!ucvector_push_back(out, (unsigned char)(LEN % 256))) return 83; + if (!ucvector_push_back(out, (unsigned char)(LEN / 256))) return 83; + if (!ucvector_push_back(out, (unsigned char)(NLEN % 256))) return 83; + if (!ucvector_push_back(out, (unsigned char)(NLEN / 256))) return 83; /*Decompressed data*/ for(j = 0; j < 65535 && datapos < datasize; j++) { - ucvector_push_back(out, data[datapos++]); + if (!ucvector_push_back(out, data[datapos++])) return 83; } } @@ -1817,17 +1851,17 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, if(error) break; if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < tree_cl.numcodes; i++) + for(i = 0; i < tree_cl.numcodes && bitlen_cl.data; i++) { /*lenghts of code length tree is in the order as specified by deflate*/ bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); } - while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) + while(bitlen_cl.data && bitlen_cl.size > 4 && bitlen_cl.data[bitlen_cl.size - 1] == 0) { /*remove zeros at the end, but minimum size must be 4*/ if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); } - if(error) break; + if(error || !bitlen_cl.data) break; /* Write everything into the output @@ -1851,15 +1885,20 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, /*write the HLIT, HDIST and HCLEN values*/ HLIT = (unsigned)(numcodes_ll - 257); HDIST = (unsigned)(numcodes_d - 1); - HCLEN = (unsigned)bitlen_cl.size - 4; + HCLEN = 0; + if (bitlen_cl.size > 4) + HCLEN = (unsigned)bitlen_cl.size - 4; /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ - while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--; + while(HCLEN > 0 && !bitlen_cl.data[HCLEN + 4 - 1]) HCLEN--; addBitsToStream(bp, out, HLIT, 5); addBitsToStream(bp, out, HDIST, 5); addBitsToStream(bp, out, HCLEN, 4); /*write the code lenghts of the code length alphabet*/ - for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); + if (bitlen_cl.size > 4) + { + for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); + } /*write the lenghts of the lit/len AND the dist alphabet*/ for(i = 0; i < bitlen_lld_e.size; i++) @@ -1913,8 +1952,15 @@ static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); - generateFixedLitLenTree(&tree_ll); - generateFixedDistanceTree(&tree_d); + error = generateFixedLitLenTree(&tree_ll); + if (error) return error; + + error = generateFixedDistanceTree(&tree_d); + if (error) + { + HuffmanTree_cleanup(&tree_ll); + return error; + } addBitToStream(bp, out, BFINAL); addBitToStream(bp, out, 1); /*first bit of BTYPE*/ @@ -2138,21 +2184,27 @@ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsig /*ucvector-controlled version of the output buffer, for dynamic array*/ ucvector_init_buffer(&outv, *out, *outsize); - ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); - ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); + if (!ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256))) return 83; + if (!ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256))) return 83; error = deflate(&deflatedata, &deflatesize, in, insize, settings); if(!error) { ADLER32 = adler32(in, (unsigned)insize); - for(i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]); + for(i = 0; i < deflatesize; i++) + { + if (!ucvector_push_back(&outv, deflatedata[i])) return 83; + } free(deflatedata); - lodepng_add32bitInt(&outv, ADLER32); + error = !lodepng_add32bitInt(&outv, ADLER32); } - *out = outv.data; - *outsize = outv.size; + if (!error) + { + *out = outv.data; + *outsize = outv.size; + } return error; } @@ -4237,7 +4289,7 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting (unsigned char*)(&data[string2_begin]), length, zlibsettings); if(error) break; - ucvector_push_back(&decoded, 0); + if (!ucvector_push_back(&decoded, 0)) ERROR_BREAK(83); error = lodepng_add_text(info, key, (char*)decoded.data); @@ -4321,7 +4373,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting length, zlibsettings); if(error) break; if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; - ucvector_push_back(&decoded, 0); + if (!ucvector_push_back(&decoded, 0)) CERROR_BREAK(error, 83 /*alloc fail*/); } else { @@ -4696,17 +4748,19 @@ static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned ch return 0; } -static void writeSignature(ucvector* out) +static unsigned writeSignature(ucvector* out) { /*8 bytes PNG signature, aka the magic bytes*/ - ucvector_push_back(out, 137); - ucvector_push_back(out, 80); - ucvector_push_back(out, 78); - ucvector_push_back(out, 71); - ucvector_push_back(out, 13); - ucvector_push_back(out, 10); - ucvector_push_back(out, 26); - ucvector_push_back(out, 10); + if (!ucvector_push_back(out, 137)) return 83; + if (!ucvector_push_back(out, 80)) return 83; + if (!ucvector_push_back(out, 78)) return 83; + if (!ucvector_push_back(out, 71)) return 83; + if (!ucvector_push_back(out, 13)) return 83; + if (!ucvector_push_back(out, 10)) return 83; + if (!ucvector_push_back(out, 26)) return 83; + if (!ucvector_push_back(out, 10)) return 83; + + return 0; } static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, @@ -4716,8 +4770,10 @@ static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, ucvector header; ucvector_init(&header); - lodepng_add32bitInt(&header, w); /*width*/ - lodepng_add32bitInt(&header, h); /*height*/ + if (!lodepng_add32bitInt(&header, w)) /*width*/ + return 1; + if (!lodepng_add32bitInt(&header, h)) /*height*/ + return 1; ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ ucvector_push_back(&header, 0); /*compression method*/ @@ -4953,9 +5009,12 @@ static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) ucvector data; ucvector_init(&data); - lodepng_add32bitInt(&data, info->phys_x); - lodepng_add32bitInt(&data, info->phys_y); - ucvector_push_back(&data, info->phys_unit); + if (!lodepng_add32bitInt(&data, info->phys_x)) + return 1; + if (!lodepng_add32bitInt(&data, info->phys_y)) + return 1; + if (!ucvector_push_back(&data, info->phys_unit)) + return 1; error = addChunk(out, "pHYs", data.data, data.size); ucvector_cleanup(&data); @@ -5092,12 +5151,16 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, size_t sum[5]; ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; - unsigned char type, bestType = 0; + unsigned char type, i, bestType = 0; for(type = 0; type < 5; type++) { ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ + if(!ucvector_resize(&attempt[type], linebytes)) + { + for(i=0; i #include #include +#include -int test_image_png_to_bmp() +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +static void *read_image(const char *src, size_t *size) +{ + int success = 0; + void *a = NULL; + long src_size; + FILE *fsrc = fopen(src, "r"); + + if (!fsrc) + goto cleanup; + + if (fseek(fsrc, 0, SEEK_END)) + goto cleanup; + + src_size = ftell(fsrc); + + if (fseek(fsrc, 0, SEEK_SET)) + goto cleanup; + + a = malloc(src_size); + + if (!a) + goto cleanup; + + if (fread(a, sizeof(char), src_size, fsrc) != src_size) + goto cleanup; + + success = 1; + *size = src_size; + +cleanup: + if (a && !success) + { + free(a); + a = NULL; + } + if (fsrc) + fclose(fsrc); + + return a; +} + + +static int compare(const char *src, const char *dst) +{ + int cmp = -1; + size_t asize, bsize; + void *a, *b; + + a = read_image(src, &asize); + b = read_image(dst, &bsize); + + if (!a || !b || (asize != bsize)) + goto cleanup; + + cmp = memcmp(a, b, asize); + +cleanup: + if (a) + free(a); + if (b) + free(b); + + return cmp; +} + +static int img_compare(wImage *image, wImage *image2) +{ + int rc = -1; + if (image->type != image2->type) + goto cleanup; + + if (image->width != image2->width) + goto cleanup; + + if (image->height != image2->height) + goto cleanup; + + if (image->scanline != image2->scanline) + goto cleanup; + + if (image->bitsPerPixel != image2->bitsPerPixel) + goto cleanup; + + if (image->bytesPerPixel != image2->bytesPerPixel) + goto cleanup; + + rc = memcmp(image->data, image2->data, image->scanline * image->height); + +cleanup: + return rc; +} + +static wImage *get_image(const char *src) { int status; - wImage* image; - - if (!PathFileExistsA("/tmp/test.png")) - return 1; /* skip */ + wImage* image = NULL; image = winpr_image_new(); if (!image) - return -1; + goto cleanup; - status = winpr_image_read(image, "/tmp/test.png"); + status = winpr_image_read(image, src); if (status < 0) + { + winpr_image_free(image, TRUE); + image = NULL; + } + +cleanup: + + return image; +} + +static int create_test(const char *src, const char *dst_png, const char *dst_bmp) +{ + int rc = -1; + int ret = -1; + int status; + size_t bsize; + void *buffer = NULL; + wImage* image = NULL, *image2 = NULL, *image3 = NULL, *image4 = NULL; + + if (!PathFileExistsA(src)) return -1; + image = get_image(src); + + /* Read from file using image methods. */ + if (!image) + goto cleanup; + + /* Write different formats to tmp. */ image->type = WINPR_IMAGE_BITMAP; - status = winpr_image_write(image, "/tmp/test_out.bmp"); + status = winpr_image_write(image, dst_bmp); if (status < 0) - return -1; + goto cleanup; image->type = WINPR_IMAGE_PNG; - status = winpr_image_write(image, "/tmp/test_out.png"); + status = winpr_image_write(image, dst_png); if (status < 0) + goto cleanup; + + /* Read image from buffer, compare. */ + buffer = read_image(src, &bsize); + if (!buffer) + goto cleanup; + + image2 = winpr_image_new(); + + if (!image2) + goto cleanup; + + status = winpr_image_read_buffer(image2, buffer, bsize); + + if (status < 0) + goto cleanup; + + rc = img_compare(image, image2); + if (rc) + goto cleanup; + + image3 = get_image(dst_png); + if (!image3) + goto cleanup; + + rc = img_compare(image, image3); + if (rc) + goto cleanup; + + image4 = get_image(dst_bmp); + if (!image4) + goto cleanup; + + image->type = WINPR_IMAGE_BITMAP; + rc = img_compare(image, image4); + if (rc) + goto cleanup; + + ret = 0; +cleanup: + if (image) + winpr_image_free(image, TRUE); + if (image2) + winpr_image_free(image2, TRUE); + if (image3) + winpr_image_free(image3, TRUE); + if (image4) + winpr_image_free(image4, TRUE); + if (buffer) + free(buffer); + + return ret; +} + +int test_image_png_to_bmp() +{ + char *buffer = TEST_SOURCE_PATH; + char src_png[PATH_MAX]; + char src_bmp[PATH_MAX]; + char dst_png[PATH_MAX]; + char dst_bmp[PATH_MAX]; + char dst_png2[PATH_MAX]; + char dst_bmp2[PATH_MAX]; + char *tmp = GetKnownPath(KNOWN_PATH_TEMP); + + if (!tmp) return -1; - winpr_image_free(image, TRUE); + if (!buffer) + return -1; + + snprintf(src_png, sizeof(src_png), "%s/lodepng_32bit.png", buffer); + snprintf(src_bmp, sizeof(src_bmp), "%s/lodepng_32bit.bmp", buffer); + snprintf(dst_png, sizeof(dst_png), "%s/lodepng_32bit.png", tmp); + snprintf(dst_bmp, sizeof(dst_bmp), "%s/lodepng_32bit.bmp", tmp); + snprintf(dst_png2, sizeof(dst_png2), "%s/lodepng_32bit-2.png", tmp); + snprintf(dst_bmp2, sizeof(dst_bmp2), "%s/lodepng_32bit-2.bmp", tmp); + + if (create_test(src_png, dst_png, dst_bmp)) + return -1; + + if (create_test(src_bmp, dst_png2, dst_bmp2)) + return -1; + +#if 0 + if (compare(dst_png2, dst_png)) + return -1; + + if (compare(dst_bmp2, dst_bmp)) + return -1; +#endif return 1; } diff --git a/winpr/libwinpr/utils/test/lodepng_32bit.bmp b/winpr/libwinpr/utils/test/lodepng_32bit.bmp new file mode 100644 index 000000000..d52d34c0c Binary files /dev/null and b/winpr/libwinpr/utils/test/lodepng_32bit.bmp differ diff --git a/winpr/libwinpr/utils/test/lodepng_32bit.png b/winpr/libwinpr/utils/test/lodepng_32bit.png new file mode 100644 index 000000000..9c55f28ea Binary files /dev/null and b/winpr/libwinpr/utils/test/lodepng_32bit.png differ