Merge pull request #2553 from akallabeth/leak_fixes

Leak fixes
This commit is contained in:
Bernhard Miklautz 2015-04-21 16:49:02 +02:00
commit d5edc63417
8 changed files with 375 additions and 93 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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];
}
}

View File

@ -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<type; i++) ucvector_cleanup(&attempt[i]);
return 83; /*alloc fail*/
}
}
if(!error)
@ -5150,13 +5213,17 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w,
float sum[5];
ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
float smallest = 0;
unsigned type, bestType = 0;
unsigned type, i, bestType = 0;
unsigned count[256];
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<type; i++) ucvector_cleanup(&attempt[i]);
return 83; /*alloc fail*/
}
}
for(y = 0; y < h; y++)
@ -5393,7 +5460,7 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const
*out = (unsigned char*)malloc(*outsize);
if(!(*out)) error = 83; /*alloc fail*/
adam7 = (unsigned char*)malloc(passstart[7]);
adam7 = (unsigned char*)calloc(passstart[7], sizeof(unsigned char));
if(!adam7 && passstart[7]) error = 83; /*alloc fail*/
if(!error)
@ -5405,7 +5472,7 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const
{
if(bpp < 8)
{
unsigned char* padded = (unsigned char*)malloc(padded_passstart[i + 1] - padded_passstart[i]);
unsigned char* padded = (unsigned char*)calloc(padded_passstart[i + 1] - padded_passstart[i], sizeof(unsigned char));
if(!padded) ERROR_BREAK(83); /*alloc fail*/
addPaddingBits(padded, &adam7[passstart[i]],
((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);

View File

@ -31,6 +31,8 @@ create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
add_definitions(-DTEST_SOURCE_PATH="${CMAKE_CURRENT_SOURCE_DIR}")
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
target_link_libraries(${MODULE_NAME} winpr)

View File

@ -3,38 +3,247 @@
#include <winpr/path.h>
#include <winpr/print.h>
#include <winpr/image.h>
#include <winpr/environment.h>
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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB