My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Macros | Typedefs | Functions | Variables
lodepng.cpp File Reference
#include "lodepng.h"
#include "portable.h"

Go to the source code of this file.

Classes

struct  vector
 
struct  uivector
 
struct  ucvector
 
struct  Coin
 
struct  HuffmanTree
 

Macros

#define USE_BRUTE_FORCE_ENCODING   1
 
#define VERSION_STRING   "20080927"
 
#define FIRST_LENGTH_CODE_INDEX   257
 
#define LAST_LENGTH_CODE_INDEX   285
 
#define NUM_DEFLATE_CODE_SYMBOLS   288 /*256 literals, the end code, some length codes, and 2 unused codes*/
 
#define NUM_DISTANCE_SYMBOLS   32 /*the distance codes have their own symbols, 30 used, 2 unused*/
 
#define NUM_CODE_LENGTH_CODES   19 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/
 
#define encodeLZ77   encodeLZ77_brute
 

Typedefs

typedef struct vector vector
 
typedef struct uivector uivector
 
typedef struct ucvector ucvector
 
typedef struct Coin Coin
 
typedef struct HuffmanTree HuffmanTree
 

Functions

static unsigned vector_resize (vector *p, size_t size)
 
static unsigned vector_resized (vector *p, size_t size, void dtor(void *))
 
static void vector_cleanup (void *p)
 
static void vector_cleanupd (vector *p, void dtor(void *))
 
static void vector_init (vector *p, unsigned typesize)
 
static void vector_swap (vector *p, vector *q)
 
static void * vector_get (vector *p, size_t index)
 
static void uivector_cleanup (void *p)
 
static unsigned uivector_resize (uivector *p, size_t size)
 
static unsigned uivector_resizev (uivector *p, size_t size, unsigned value)
 
static void uivector_init (uivector *p)
 
static unsigned uivector_push_back (uivector *p, unsigned c)
 
static unsigned uivector_copy (uivector *p, const uivector *q)
 
static void uivector_swap (uivector *p, uivector *q)
 
static void ucvector_cleanup (void *p)
 
static unsigned ucvector_resize (ucvector *p, size_t size)
 
static void ucvector_init (ucvector *p)
 
static void ucvector_init_buffer (ucvector *p, unsigned char *buffer, size_t size)
 
static unsigned ucvector_push_back (ucvector *p, unsigned char c)
 
static void addBitToStream (size_t *bitpointer, ucvector *bitstream, unsigned char bit)
 
static void addBitsToStream (size_t *bitpointer, ucvector *bitstream, unsigned value, size_t nbits)
 
static void addBitsToStreamReversed (size_t *bitpointer, ucvector *bitstream, unsigned value, size_t nbits)
 
static void Coin_init (Coin *c)
 
static void Coin_cleanup (void *c)
 
static void Coin_copy (Coin *c1, const Coin *c2)
 
static void addCoins (Coin *c1, const Coin *c2)
 
static void Coin_sort (Coin *data, size_t amount)
 
static void HuffmanTree_init (HuffmanTree *tree)
 
static void HuffmanTree_cleanup (HuffmanTree *tree)
 
static unsigned HuffmanTree_make2DTree (HuffmanTree *tree)
 
static unsigned HuffmanTree_makeFromLengths2 (HuffmanTree *tree)
 
static unsigned HuffmanTree_makeFromLengths (HuffmanTree *tree, const unsigned *bitlen, size_t numcodes, unsigned maxbitlen)
 
static unsigned HuffmanTree_fillInCoins (vector *coins, const unsigned *frequencies, unsigned numcodes, size_t sum)
 
static unsigned HuffmanTree_makeFromFrequencies (HuffmanTree *tree, const unsigned *frequencies, size_t numcodes, unsigned maxbitlen)
 
static unsigned HuffmanTree_getCode (const HuffmanTree *tree, unsigned index)
 
static unsigned HuffmanTree_getLength (const HuffmanTree *tree, unsigned index)
 
static unsigned generateFixedTree (HuffmanTree *tree)
 
static unsigned generateDistanceTree (HuffmanTree *tree)
 
static void addHuffmanSymbol (size_t *bp, ucvector *compressed, unsigned code, unsigned bitlen)
 
static size_t searchCodeIndex (const unsigned *array, size_t array_size, size_t value)
 
static void addLengthDistance (uivector *values, size_t length, size_t distance)
 
static unsigned encodeLZ77_brute (uivector *out, const unsigned char *in, size_t size, unsigned windowSize)
 
static unsigned deflateNoCompression (ucvector *out, const unsigned char *data, size_t datasize)
 
static void writeLZ77data (size_t *bp, ucvector *out, const uivector *lz77_encoded, const HuffmanTree *codes, const HuffmanTree *codesD)
 
static unsigned deflateDynamic (ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
 
static unsigned deflateFixed (ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
 
unsigned LodeFlate_deflate (ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
 
static unsigned update_adler32 (unsigned adler, const unsigned char *data, unsigned len)
 
static unsigned adler32 (const unsigned char *data, unsigned len)
 
void LodeZlib_add32bitInt (ucvector *buffer, unsigned value)
 
unsigned LodeZlib_read32bitInt (const unsigned char *buffer)
 
unsigned LodeZlib_compress (unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodeZlib_DeflateSettings *settings)
 
void LodeZlib_DeflateSettings_init (LodeZlib_DeflateSettings *settings)
 
static unsigned LodePNG_compress (unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodeZlib_DeflateSettings *settings)
 
static void Crc32_make_crc_table (void)
 
static unsigned Crc32_update_crc (const unsigned char *buf, unsigned int crc, size_t len)
 
static unsigned Crc32_crc (const unsigned char *buf, size_t len)
 
static unsigned char readBitFromReversedStream (size_t *bitpointer, const unsigned char *bitstream)
 
static unsigned readBitsFromReversedStream (size_t *bitpointer, const unsigned char *bitstream, size_t nbits)
 
static void setBitOfReversedStream (size_t *bitpointer, unsigned char *bitstream, unsigned char bit)
 
static unsigned LodePNG_read32bitInt (const unsigned char *buffer)
 
static void LodePNG_set32bitInt (unsigned char *buffer, unsigned value)
 
static void LodePNG_add32bitInt (ucvector *buffer, unsigned value)
 
unsigned LodePNG_chunk_length (const unsigned char *chunk)
 
void LodePNG_chunk_type (char type[5], const unsigned char *chunk)
 
unsigned char LodePNG_chunk_type_equals (const unsigned char *chunk, const char *type)
 
unsigned char LodePNG_chunk_critical (const unsigned char *chunk)
 
unsigned char LodePNG_chunk_private (const unsigned char *chunk)
 
unsigned char LodePNG_chunk_safetocopy (const unsigned char *chunk)
 
unsigned char * LodePNG_chunk_data (unsigned char *chunk)
 
const unsigned char * LodePNG_chunk_data_const (const unsigned char *chunk)
 
unsigned LodePNG_chunk_check_crc (const unsigned char *chunk)
 
void LodePNG_chunk_generate_crc (unsigned char *chunk)
 
unsigned char * LodePNG_chunk_next (unsigned char *chunk)
 
const unsigned char * LodePNG_chunk_next_const (const unsigned char *chunk)
 
unsigned LodePNG_append_chunk (unsigned char **out, size_t *outlength, const unsigned char *chunk)
 
unsigned LodePNG_create_chunk (unsigned char **out, size_t *outlength, unsigned length, const char *type, const unsigned char *data)
 
static unsigned checkColorValidity (unsigned colorType, unsigned bd)
 
static unsigned getNumColorChannels (unsigned colorType)
 
static unsigned getBpp (unsigned colorType, unsigned bitDepth)
 
void LodePNG_InfoColor_init (LodePNG_InfoColor *info)
 
void LodePNG_InfoColor_cleanup (LodePNG_InfoColor *info)
 
void LodePNG_InfoColor_clearPalette (LodePNG_InfoColor *info)
 
unsigned LodePNG_InfoColor_addPalette (LodePNG_InfoColor *info, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
 
unsigned LodePNG_InfoColor_getBpp (const LodePNG_InfoColor *info)
 
unsigned LodePNG_InfoColor_getChannels (const LodePNG_InfoColor *info)
 
unsigned LodePNG_InfoColor_isGreyscaleType (const LodePNG_InfoColor *info)
 
unsigned LodePNG_InfoColor_isAlphaType (const LodePNG_InfoColor *info)
 
unsigned LodePNG_InfoColor_equal (const LodePNG_InfoColor *info1, const LodePNG_InfoColor *info2)
 
void LodePNG_InfoPng_init (LodePNG_InfoPng *info)
 
void LodePNG_InfoPng_cleanup (LodePNG_InfoPng *info)
 
unsigned LodePNG_InfoPng_copy (LodePNG_InfoPng *dest, const LodePNG_InfoPng *source)
 
void LodePNG_InfoPng_swap (LodePNG_InfoPng *a, LodePNG_InfoPng *b)
 
unsigned LodePNG_InfoColor_copy (LodePNG_InfoColor *dest, const LodePNG_InfoColor *source)
 
void LodePNG_InfoRaw_init (LodePNG_InfoRaw *info)
 
void LodePNG_InfoRaw_cleanup (LodePNG_InfoRaw *info)
 
unsigned LodePNG_InfoRaw_copy (LodePNG_InfoRaw *dest, const LodePNG_InfoRaw *source)
 
unsigned LodePNG_convert (unsigned char *out, const unsigned char *in, LodePNG_InfoColor *infoOut, LodePNG_InfoColor *infoIn, unsigned w, unsigned h)
 
static int paethPredictor (int a, int b, int c)
 
static void Adam7_getpassvalues (unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
 
static unsigned addChunk (ucvector *out, const char *chunkName, const unsigned char *data, size_t length)
 
static void writeSignature (ucvector *out)
 
static unsigned addChunk_IHDR (ucvector *out, unsigned w, unsigned h, unsigned bitDepth, unsigned colorType, unsigned interlaceMethod)
 
static unsigned addChunk_PLTE (ucvector *out, const LodePNG_InfoColor *info)
 
static unsigned addChunk_tRNS (ucvector *out, const LodePNG_InfoColor *info)
 
static unsigned addChunk_IDAT (ucvector *out, const unsigned char *data, size_t datasize, LodeZlib_DeflateSettings *zlibsettings)
 
static unsigned addChunk_IEND (ucvector *out)
 
static void filterScanline (unsigned char *out, const unsigned char *scanline, const unsigned char *prevline, size_t length, size_t bytewidth, unsigned char filterType)
 
static unsigned filter (unsigned char *out, const unsigned char *in, unsigned w, unsigned h, const LodePNG_InfoColor *info)
 
static void addPaddingBits (unsigned char *out, const unsigned char *in, size_t olinebits, size_t ilinebits, unsigned h)
 
static void Adam7_interlace (unsigned char *out, const unsigned char *in, unsigned w, unsigned h, unsigned bpp)
 
static unsigned preProcessScanlines (unsigned char **out, size_t *outsize, const unsigned char *in, const LodePNG_InfoPng *infoPng)
 
static unsigned isPaletteFullyOpaque (const unsigned char *palette, size_t palettesize)
 
static unsigned isFullyOpaque (const unsigned char *image, unsigned w, unsigned h, const LodePNG_InfoColor *info)
 
void LodePNG_encode (LodePNG_Encoder *encoder, unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
 
unsigned LodePNG_encode32 (unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
 
unsigned LodePNG_encode32f (const char *filename, const unsigned char *image, unsigned w, unsigned h)
 
void LodePNG_EncodeSettings_init (LodePNG_EncodeSettings *settings)
 
void LodePNG_Encoder_init (LodePNG_Encoder *encoder)
 
void LodePNG_Encoder_cleanup (LodePNG_Encoder *encoder)
 
void LodePNG_Encoder_copy (LodePNG_Encoder *dest, const LodePNG_Encoder *source)
 
unsigned LodePNG_loadFile (unsigned char **out, size_t *outsize, const char *filename)
 
unsigned LodePNG_saveFile (const unsigned char *buffer, size_t buffersize, const char *filename)
 

Variables

static const unsigned LENGTHBASE [29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}
 
static const unsigned LENGTHEXTRA [29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}
 
static const unsigned DISTANCEBASE [30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}
 
static const unsigned DISTANCEEXTRA [30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}
 
static const unsigned CLCL [NUM_CODE_LENGTH_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
 
static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258
 
const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings = {2, 1, 2048}
 
static unsigned Crc32_crc_table_computed = 0
 
static unsigned Crc32_crc_table [256]
 
static const unsigned ADAM7_IX [7] = { 0, 4, 0, 2, 0, 1, 0 }
 
static const unsigned ADAM7_IY [7] = { 0, 0, 4, 0, 2, 0, 1 }
 
static const unsigned ADAM7_DX [7] = { 8, 8, 4, 4, 2, 2, 1 }
 
static const unsigned ADAM7_DY [7] = { 8, 8, 8, 4, 4, 2, 2 }
 

Macro Definition Documentation

#define encodeLZ77   encodeLZ77_brute

Definition at line 1039 of file lodepng.cpp.

Referenced by deflateDynamic(), and deflateFixed().

#define FIRST_LENGTH_CODE_INDEX   257

Definition at line 347 of file lodepng.cpp.

Referenced by addLengthDistance(), and writeLZ77data().

#define LAST_LENGTH_CODE_INDEX   285

Definition at line 348 of file lodepng.cpp.

#define NUM_CODE_LENGTH_CODES   19 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/

Definition at line 351 of file lodepng.cpp.

#define NUM_DEFLATE_CODE_SYMBOLS   288 /*256 literals, the end code, some length codes, and 2 unused codes*/

Definition at line 349 of file lodepng.cpp.

Referenced by generateFixedTree().

#define NUM_DISTANCE_SYMBOLS   32 /*the distance codes have their own symbols, 30 used, 2 unused*/

Definition at line 350 of file lodepng.cpp.

Referenced by generateDistanceTree().

#define USE_BRUTE_FORCE_ENCODING   1

Definition at line 34 of file lodepng.cpp.

#define VERSION_STRING   "20080927"

Definition at line 36 of file lodepng.cpp.

Referenced by LodePNG_encode().

Typedef Documentation

typedef struct Coin Coin
typedef struct HuffmanTree HuffmanTree
typedef struct ucvector ucvector
typedef struct uivector uivector
typedef struct vector vector

Function Documentation

static void Adam7_getpassvalues ( unsigned  passw[7],
unsigned  passh[7],
size_t  filter_passstart[8],
size_t  padded_passstart[8],
size_t  passstart[8],
unsigned  w,
unsigned  h,
unsigned  bpp 
)
static

Definition at line 2570 of file lodepng.cpp.

Referenced by Adam7_interlace(), and preProcessScanlines().

{
/*the passstart values have 8 values: the 8th one actually indicates the byte after the end of the 7th (= last) pass*/
unsigned i;
/*calculate width and height in pixels of each pass*/
for(i = 0; i < 7; i++)
{
passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
if(passw[i] == 0) passh[i] = 0;
if(passh[i] == 0) passw[i] = 0;
}
filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
for(i = 0; i < 7; i++)
{
filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/
padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); /*bits padded if needed to fill full byte at end of each scanline*/
passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; /*only padded at end of reduced image*/
}
}
static void Adam7_interlace ( unsigned char *  out,
const unsigned char *  in,
unsigned  w,
unsigned  h,
unsigned  bpp 
)
static

Definition at line 3712 of file lodepng.cpp.

References Adam7_getpassvalues(), readBitFromReversedStream(), and setBitOfReversedStream().

Referenced by preProcessScanlines().

{
/*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding*/
unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
unsigned i;
Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
if(bpp >= 8)
{
for(i = 0; i < 7; i++)
{
unsigned x, y, b;
size_t bytewidth = bpp / 8;
for(y = 0; y < passh[i]; y++)
for(x = 0; x < passw[i]; x++)
{
size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
for(b = 0; b < bytewidth; b++)
{
out[pixeloutstart + b] = in[pixelinstart + b];
}
}
}
}
else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
{
for(i = 0; i < 7; i++)
{
unsigned x, y, b;
unsigned ilinebits = bpp * passw[i];
unsigned olinebits = bpp * w;
size_t obp, ibp; /*bit pointers (for out and in buffer)*/
for(y = 0; y < passh[i]; y++)
for(x = 0; x < passw[i]; x++)
{
ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
for(b = 0; b < bpp; b++)
{
unsigned char bit = readBitFromReversedStream(&ibp, in);
setBitOfReversedStream(&obp, out, bit);
}
}
}
}
}
static void addBitsToStream ( size_t *  bitpointer,
ucvector bitstream,
unsigned  value,
size_t  nbits 
)
static

Definition at line 314 of file lodepng.cpp.

Referenced by deflateDynamic(), and writeLZ77data().

{
size_t i;
for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1));
}
static void addBitsToStreamReversed ( size_t *  bitpointer,
ucvector bitstream,
unsigned  value,
size_t  nbits 
)
static

Definition at line 320 of file lodepng.cpp.

Referenced by addHuffmanSymbol().

{
size_t i;
for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1));
}
static void addBitToStream ( size_t *  bitpointer,
ucvector bitstream,
unsigned char  bit 
)
static

Definition at line 307 of file lodepng.cpp.

References ucvector::data, ucvector::size, and ucvector_push_back().

Referenced by deflateDynamic(), and deflateFixed().

{
if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, 0); /*add a new byte at the end*/
(bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
(*bitpointer)++;
}
static unsigned addChunk ( ucvector out,
const char *  chunkName,
const unsigned char *  data,
size_t  length 
)
static

Definition at line 3277 of file lodepng.cpp.

References ucvector::allocsize, ucvector::data, LodePNG_create_chunk(), and ucvector::size.

Referenced by addChunk_IDAT(), addChunk_IEND(), addChunk_IHDR(), addChunk_PLTE(), and addChunk_tRNS().

{
unsigned error = LodePNG_create_chunk(&out->data, &out->size, (unsigned)length, chunkName, data);
if(error) return error;
out->allocsize = out->size; /*fix the allocsize again*/
return 0;
}
static unsigned addChunk_IDAT ( ucvector out,
const unsigned char *  data,
size_t  datasize,
LodeZlib_DeflateSettings zlibsettings 
)
static

Definition at line 3368 of file lodepng.cpp.

References addChunk(), ucvector::data, LodePNG_compress(), ucvector::size, ucvector_cleanup(), and ucvector_init().

Referenced by LodePNG_encode().

{
ucvector zlibdata;
unsigned error = 0;
/*compress with the Zlib compressor*/
ucvector_init(&zlibdata);
error = LodePNG_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings);
if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size);
ucvector_cleanup(&zlibdata);
return error;
}
static unsigned addChunk_IEND ( ucvector out)
static

Definition at line 3382 of file lodepng.cpp.

References addChunk().

Referenced by LodePNG_encode().

{
unsigned error = 0;
error = addChunk(out, "IEND", 0, 0);
return error;
}
static unsigned addChunk_IHDR ( ucvector out,
unsigned  w,
unsigned  h,
unsigned  bitDepth,
unsigned  colorType,
unsigned  interlaceMethod 
)
static

Definition at line 3298 of file lodepng.cpp.

References addChunk(), ucvector::data, LodePNG_add32bitInt(), ucvector::size, ucvector_cleanup(), ucvector_init(), and ucvector_push_back().

Referenced by LodePNG_encode().

{
unsigned error = 0;
ucvector header;
ucvector_init(&header);
LodePNG_add32bitInt(&header, w); /*width*/
LodePNG_add32bitInt(&header, h); /*height*/
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*/
ucvector_push_back(&header, 0); /*filter method*/
ucvector_push_back(&header, interlaceMethod); /*interlace method*/
error = addChunk(out, "IHDR", header.data, header.size);
ucvector_cleanup(&header);
return error;
}
static unsigned addChunk_PLTE ( ucvector out,
const LodePNG_InfoColor info 
)
static

Definition at line 3318 of file lodepng.cpp.

References addChunk(), ucvector::data, LodePNG_InfoColor::palette, LodePNG_InfoColor::palettesize, ucvector::size, ucvector_cleanup(), ucvector_init(), and ucvector_push_back().

Referenced by LodePNG_encode().

{
unsigned error = 0;
size_t i;
ucvector PLTE;
ucvector_init(&PLTE);
for(i = 0; i < info->palettesize * 4; i++) if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); /*add all channels except alpha channel*/
error = addChunk(out, "PLTE", PLTE.data, PLTE.size);
return error;
}
static unsigned addChunk_tRNS ( ucvector out,
const LodePNG_InfoColor info 
)
static

Definition at line 3331 of file lodepng.cpp.

References addChunk(), LodePNG_InfoColor::colorType, ucvector::data, LodePNG_InfoColor::key_b, LodePNG_InfoColor::key_defined, LodePNG_InfoColor::key_g, LodePNG_InfoColor::key_r, LodePNG_InfoColor::palette, LodePNG_InfoColor::palettesize, ucvector::size, ucvector_cleanup(), ucvector_init(), and ucvector_push_back().

Referenced by LodePNG_encode().

{
unsigned error = 0;
size_t i;
ucvector tRNS;
ucvector_init(&tRNS);
if(info->colorType == 3)
{
for(i = 0; i < info->palettesize; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); /*add only alpha channel*/
}
else if(info->colorType == 0)
{
if(info->key_defined)
{
ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
}
}
else if(info->colorType == 2)
{
if(info->key_defined)
{
ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256));
ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256));
}
}
error = addChunk(out, "tRNS", tRNS.data, tRNS.size);
return error;
}
static void addCoins ( Coin c1,
const Coin c2 
)
static

Definition at line 390 of file lodepng.cpp.

References uivector::data, uivector::size, Coin::symbols, uivector_push_back(), and Coin::weight.

Referenced by HuffmanTree_makeFromFrequencies().

{
unsigned i;
for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]);
c1->weight += c2->weight;
}
static void addHuffmanSymbol ( size_t *  bp,
ucvector compressed,
unsigned  code,
unsigned  bitlen 
)
static

Definition at line 994 of file lodepng.cpp.

References addBitsToStreamReversed().

Referenced by deflateDynamic(), deflateFixed(), and writeLZ77data().

{
addBitsToStreamReversed(bp, compressed, code, bitlen);
}
static void addLengthDistance ( uivector values,
size_t  length,
size_t  distance 
)
static

Definition at line 1019 of file lodepng.cpp.

References DISTANCEBASE, FIRST_LENGTH_CODE_INDEX, LENGTHBASE, searchCodeIndex(), and uivector_push_back().

Referenced by encodeLZ77_brute().

{
/*values in encoded vector are those used by deflate:
0-255: literal bytes
256: end
257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits)
286-287: invalid*/
unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
uivector_push_back(values, extra_length);
uivector_push_back(values, dist_code);
uivector_push_back(values, extra_distance);
}
static void addPaddingBits ( unsigned char *  out,
const unsigned char *  in,
size_t  olinebits,
size_t  ilinebits,
unsigned  h 
)
static

Definition at line 3692 of file lodepng.cpp.

References readBitFromReversedStream(), and setBitOfReversedStream().

Referenced by preProcessScanlines().

{
/*The opposite of the removePaddingBits function
olinebits must be >= ilinebits*/
unsigned y;
size_t diff = olinebits - ilinebits;
size_t obp = 0, ibp = 0; /*bit pointers*/
for(y = 0; y < h; y++)
{
size_t x;
for(x = 0; x < ilinebits; x++)
{
unsigned char bit = readBitFromReversedStream(&ibp, in);
setBitOfReversedStream(&obp, out, bit);
}
/*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/
for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0);
}
}
static unsigned adler32 ( const unsigned char *  data,
unsigned  len 
)
static

Definition at line 1582 of file lodepng.cpp.

References update_adler32().

Referenced by LodeZlib_compress().

{
return update_adler32(1L, data, len);
}
static unsigned checkColorValidity ( unsigned  colorType,
unsigned  bd 
)
static

Definition at line 1991 of file lodepng.cpp.

Referenced by LodePNG_encode().

{
switch(colorType)
{
case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/
case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/
case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/
case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/
case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/
default: return 31;
}
return 0; /*allowed color type / bits combination*/
}
static void Coin_cleanup ( void *  c)
static

Definition at line 379 of file lodepng.cpp.

References uivector_cleanup().

Referenced by HuffmanTree_makeFromFrequencies().

{
uivector_cleanup(&((Coin*)c)->symbols);
}
static void Coin_copy ( Coin c1,
const Coin c2 
)
static

Definition at line 384 of file lodepng.cpp.

References Coin::symbols, uivector_copy(), and Coin::weight.

Referenced by HuffmanTree_makeFromFrequencies().

{
c1->weight = c2->weight;
}
static void Coin_init ( Coin c)
static

Definition at line 374 of file lodepng.cpp.

References Coin::symbols, and uivector_init().

Referenced by HuffmanTree_fillInCoins(), and HuffmanTree_makeFromFrequencies().

static void Coin_sort ( Coin data,
size_t  amount 
)
static

Definition at line 397 of file lodepng.cpp.

References uivector_swap(), and Coin::weight.

Referenced by HuffmanTree_fillInCoins().

{
size_t gap = amount;
unsigned char swapped = 0;
while(gap > 1 || swapped)
{
size_t i;
gap = (gap * 10) / 13; /*shrink factor 1.3*/
if(gap == 9 || gap == 10) gap = 11; /*combsort11*/
if(gap < 1) gap = 1;
swapped = 0;
for(i = 0; i < amount - gap; i++)
{
size_t j = i + gap;
if(data[j].weight < data[i].weight)
{
float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp;
uivector_swap(&data[i].symbols, &data[j].symbols);
swapped = 1;
}
}
}
}
static unsigned Crc32_crc ( const unsigned char *  buf,
size_t  len 
)
static

Definition at line 1799 of file lodepng.cpp.

References Crc32_update_crc().

Referenced by LodePNG_chunk_check_crc(), and LodePNG_chunk_generate_crc().

{
return Crc32_update_crc(buf, 0xffffffffu, len) ^ 0xffffffffu;
}
static void Crc32_make_crc_table ( void  )
static

Definition at line 1766 of file lodepng.cpp.

Referenced by Crc32_update_crc().

{
unsigned int c, k, n;
for(n = 0; n < 256; n++)
{
c = n;
for(k = 0; k < 8; k++)
{
if(c & 1) c = (unsigned int)(0xedb88320L ^ (c >> 1));
else c = c >> 1;
}
}
}
static unsigned Crc32_update_crc ( const unsigned char *  buf,
unsigned int  crc,
size_t  len 
)
static

Definition at line 1785 of file lodepng.cpp.

References Crc32_make_crc_table().

Referenced by Crc32_crc().

{
unsigned int c = crc;
size_t n;
for(n = 0; n < len; n++)
{
c = Crc32_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c;
}
static unsigned deflateDynamic ( ucvector out,
const unsigned char *  data,
size_t  datasize,
const LodeZlib_DeflateSettings settings 
)
static

Definition at line 1327 of file lodepng.cpp.

References addBitsToStream(), addBitToStream(), addHuffmanSymbol(), CLCL, uivector::data, encodeLZ77, HuffmanTree_cleanup(), HuffmanTree_getCode(), HuffmanTree_getLength(), HuffmanTree_init(), HuffmanTree_makeFromFrequencies(), HuffmanTree::numcodes, uivector::size, uivector_cleanup(), uivector_init(), uivector_push_back(), uivector_resize(), uivector_resizev(), LodeZlib_DeflateSettings::useLZ77, LodeZlib_DeflateSettings::windowSize, and writeLZ77data().

Referenced by LodeFlate_deflate().

{
/*
after the BFINAL and BTYPE, the dynamic block consists out of the following:
- 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN
- (HCLEN+4)*3 bits code lengths of code length alphabet
- HLIT + 257 code lengths of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
- HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
- compressed data
- 256 (end code)
*/
unsigned error = 0;
uivector lz77_encoded;
HuffmanTree codes; /*tree for literal values and length codes*/
HuffmanTree codesD; /*tree for distance codes*/
HuffmanTree codelengthcodes;
uivector frequencies;
uivector frequenciesD;
uivector amounts; /*the amounts in the "normal" order*/
uivector lldl;
uivector lldll; /*lit/len & dist code lengths*/
uivector clcls;
unsigned BFINAL = 1; /*make only one block... the first and final one*/
size_t numcodes, numcodesD, i, bp = 0; /*the bit pointer*/
unsigned HLIT, HDIST, HCLEN;
uivector_init(&lz77_encoded);
HuffmanTree_init(&codesD);
HuffmanTree_init(&codelengthcodes);
uivector_init(&frequencies);
uivector_init(&frequenciesD);
uivector_init(&amounts);
uivector_init(&lldl);
uivector_init(&lldll);
uivector_init(&clcls);
while(!error) /*the goto-avoiding while construct: break out to go to the cleanup phase, a break at the end makes sure the while is never repeated*/
{
if(settings->useLZ77)
{
error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize); /*LZ77 encoded*/
if(error) break;
}
else
{
if(!uivector_resize(&lz77_encoded, datasize)) { error = 9923; break; }
for(i = 0; i < datasize; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/
}
if(!uivector_resizev(&frequencies, 286, 0)) { error = 9924; break; }
if(!uivector_resizev(&frequenciesD, 30, 0)) { error = 9925; break; }
for(i = 0; i < lz77_encoded.size; i++)
{
unsigned symbol = lz77_encoded.data[i];
frequencies.data[symbol]++;
if(symbol > 256)
{
unsigned dist = lz77_encoded.data[i + 2];
frequenciesD.data[dist]++;
i += 3;
}
}
frequencies.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/
error = HuffmanTree_makeFromFrequencies(&codes, frequencies.data, frequencies.size, 15);
if(error) break;
error = HuffmanTree_makeFromFrequencies(&codesD, frequenciesD.data, frequenciesD.size, 15);
if(error) break;
addBitToStream(&bp, out, BFINAL);
addBitToStream(&bp, out, 0); /*first bit of BTYPE "dynamic"*/
addBitToStream(&bp, out, 1); /*second bit of BTYPE "dynamic"*/
numcodes = codes.numcodes; if(numcodes > 286) numcodes = 286;
numcodesD = codesD.numcodes; if(numcodesD > 30) numcodesD = 30;
for(i = 0; i < numcodes; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codes, (unsigned)i));
for(i = 0; i < numcodesD; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codesD, (unsigned)i));
/*make lldl smaller by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeros), 18 (11-138 zeros)*/
for(i = 0; i < (unsigned)lldll.size; i++)
{
unsigned j = 0;
while(i + j + 1 < (unsigned)lldll.size && lldll.data[i + j + 1] == lldll.data[i]) j++;
if(lldll.data[i] == 0 && j >= 2)
{
j++; /*include the first zero*/
if(j <= 10) { uivector_push_back(&lldl, 17); uivector_push_back(&lldl, j - 3); }
else
{
if(j > 138) j = 138;
uivector_push_back(&lldl, 18); uivector_push_back(&lldl, j - 11);
}
i += (j - 1);
}
else if(j >= 3)
{
size_t k;
unsigned num = j / 6, rest = j % 6;
uivector_push_back(&lldl, lldll.data[i]);
for(k = 0; k < num; k++) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, 6 - 3); }
if(rest >= 3) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, rest - 3); }
else j -= rest;
i += j;
}
else uivector_push_back(&lldl, lldll.data[i]);
}
/*generate huffmantree for the length codes of lit/len and dist codes*/
if(!uivector_resizev(&amounts, 19, 0)) { error = 9926; break; } /*16 possible lengths (0-15) and 3 repeat codes (16, 17 and 18)*/
for(i = 0; i < lldl.size; i++)
{
amounts.data[lldl.data[i]]++;
if(lldl.data[i] >= 16) i++; /*after a repeat code come the bits that specify the amount, those don't need to be in the amounts calculation*/
}
error = HuffmanTree_makeFromFrequencies(&codelengthcodes, amounts.data, amounts.size, 7);
if(error) break;
if(!uivector_resize(&clcls, 19)) { error = 9927; break; }
for(i = 0; i < 19; i++) clcls.data[i] = HuffmanTree_getLength(&codelengthcodes, CLCL[i]); /*lengths of code length tree is in the order as specified by deflate*/
while(clcls.data[clcls.size - 1] == 0 && clcls.size > 4)
{
if(!uivector_resize(&clcls, clcls.size - 1)) { error = 9928; break; } /*remove zeros at the end, but minimum size must be 4*/
}
if(error) break;
/*write the HLIT, HDIST and HCLEN values*/
HLIT = (unsigned)(numcodes - 257);
HDIST = (unsigned)(numcodesD - 1);
HCLEN = (unsigned)clcls.size - 4;
addBitsToStream(&bp, out, HLIT, 5);
addBitsToStream(&bp, out, HDIST, 5);
addBitsToStream(&bp, out, HCLEN, 4);
/*write the code lengths of the code length alphabet*/
for(i = 0; i < HCLEN + 4; i++) addBitsToStream(&bp, out, clcls.data[i], 3);
/*write the lengths of the lit/len AND the dist alphabet*/
for(i = 0; i < lldl.size; i++)
{
addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codelengthcodes, lldl.data[i]), HuffmanTree_getLength(&codelengthcodes, lldl.data[i]));
/*extra bits of repeat codes*/
if(lldl.data[i] == 16) addBitsToStream(&bp, out, lldl.data[++i], 2);
else if(lldl.data[i] == 17) addBitsToStream(&bp, out, lldl.data[++i], 3);
else if(lldl.data[i] == 18) addBitsToStream(&bp, out, lldl.data[++i], 7);
}
/*write the compressed data symbols*/
writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
if(HuffmanTree_getLength(&codes, 256) == 0) { error = 64; break; } /*the length of the end code 256 must be larger than 0*/
addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*end code*/
break; /*end of error-while*/
}
/*cleanup*/
uivector_cleanup(&lz77_encoded);
HuffmanTree_cleanup(&codelengthcodes);
uivector_cleanup(&frequencies);
uivector_cleanup(&frequenciesD);
uivector_cleanup(&amounts);
return error;
}
static unsigned deflateFixed ( ucvector out,
const unsigned char *  data,
size_t  datasize,
const LodeZlib_DeflateSettings settings 
)
static

Definition at line 1502 of file lodepng.cpp.

References addBitToStream(), addHuffmanSymbol(), encodeLZ77, generateDistanceTree(), generateFixedTree(), HuffmanTree_cleanup(), HuffmanTree_getCode(), HuffmanTree_getLength(), HuffmanTree_init(), uivector_cleanup(), uivector_init(), LodeZlib_DeflateSettings::useLZ77, LodeZlib_DeflateSettings::windowSize, and writeLZ77data().

Referenced by LodeFlate_deflate().

{
HuffmanTree codes; /*tree for literal values and length codes*/
HuffmanTree codesD; /*tree for distance codes*/
unsigned BFINAL = 1; /*make only one block... the first and final one*/
unsigned error = 0;
size_t i, bp = 0; /*the bit pointer*/
HuffmanTree_init(&codesD);
addBitToStream(&bp, out, BFINAL);
addBitToStream(&bp, out, 1); /*first bit of BTYPE*/
addBitToStream(&bp, out, 0); /*second bit of BTYPE*/
if(settings->useLZ77) /*LZ77 encoded*/
{
uivector lz77_encoded;
uivector_init(&lz77_encoded);
error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize);
if(!error) writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
uivector_cleanup(&lz77_encoded);
}
else /*no LZ77, but still will be Huffman compressed*/
{
for(i = 0; i < datasize; i++) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, data[i]), HuffmanTree_getLength(&codes, data[i]));
}
if(!error) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*"end" code*/
/*cleanup*/
return error;
}
static unsigned deflateNoCompression ( ucvector out,
const unsigned char *  data,
size_t  datasize 
)
static

Definition at line 1264 of file lodepng.cpp.

References ucvector_push_back().

Referenced by LodeFlate_deflate().

{
/*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/
size_t i, j, numdeflateblocks = datasize / 65536 + 1;
unsigned datapos = 0;
for(i = 0; i < numdeflateblocks; i++)
{
unsigned BFINAL, BTYPE, LEN, NLEN;
unsigned char firstbyte;
BFINAL = (i == numdeflateblocks - 1);
BTYPE = 0;
firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
ucvector_push_back(out, firstbyte);
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));
/*Decompressed data*/
for(j = 0; j < 65535 && datapos < datasize; j++)
{
ucvector_push_back(out, data[datapos++]);
}
}
return 0;
}
static unsigned encodeLZ77_brute ( uivector out,
const unsigned char *  in,
size_t  size,
unsigned  windowSize 
)
static

search for the longest string

encode it as length/distance pair or literal value

Definition at line 1041 of file lodepng.cpp.

References addLengthDistance(), and uivector_push_back().

{
size_t pos;
/*using pointer instead of vector for input makes it faster when NOT using optimization when compiling; no influence if optimization is used*/
for(pos = 0; pos < size; pos++)
{
/*Phase 1: doxygen images often have long runs of the same color, try to find them*/
const int minLength = 4; // Minimum length for a run to make sense
if(pos < size - minLength * 4)
{
size_t p, fp;
size_t current_length;
/*RGBA pixel run?*/
p = pos;
fp = pos + 4;
current_length = 0;
while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
{
++p;
++fp;
++current_length;
}
if (current_length > (minLength - 1 ) * 4) /*worth using?*/
{
uivector_push_back(out, in[pos ]);
uivector_push_back(out, in[pos + 1]);
uivector_push_back(out, in[pos + 2]);
uivector_push_back(out, in[pos + 3]);
addLengthDistance(out, current_length, 4);
pos += current_length + 4 - 1; /*-1 for loop's pos++*/
continue;
}
/*RGB pixel run?*/
p = pos;
fp = pos + 3;
current_length = 0;
while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
{
++p;
++fp;
++current_length;
}
if (current_length > (minLength - 1 ) * 3) /*worth using?*/
{
uivector_push_back(out, in[pos ]);
uivector_push_back(out, in[pos + 1]);
uivector_push_back(out, in[pos + 2]);
addLengthDistance(out, current_length, 3);
pos += current_length + 3 - 1; /*-1 for loop's pos++*/
continue;
}
}
size_t length = 0, offset = 0; /*the length and offset found for the current position*/
size_t max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/
size_t current_offset;
for(current_offset = 1; current_offset < max_offset; current_offset++) /*search backwards through all possible distances (=offsets)*/
{
size_t backpos = pos - current_offset;
if(in[backpos] == in[pos])
{
/*test the next characters*/
size_t current_length = 1;
size_t backtest = backpos + 1;
size_t foretest = pos + 1;
while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum support length by deflate is max length*/
{
if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/
current_length++;
backtest++;
foretest++;
}
if(current_length > length)
{
length = current_length; /*the longest length*/
offset = current_offset; /*the offset that is related to this longest length*/
if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/
}
}
}
if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
{
uivector_push_back(out, in[pos]);
}
else
{
addLengthDistance(out, length, offset);
pos += (length - 1);
}
} /*end of the loop through each character of input*/
return 0;
}
static unsigned filter ( unsigned char *  out,
const unsigned char *  in,
unsigned  w,
unsigned  h,
const LodePNG_InfoColor info 
)
static

Definition at line 3576 of file lodepng.cpp.

References LodePNG_InfoColor::bitDepth, LodeZlib_DeflateSettings::btype, LodePNG_InfoColor::colorType, ucvector::data, filterScanline(), LodePNG_compress(), LodePNG_InfoColor_getBpp(), LodeZlib_defaultDeflateSettings, ucvector::size, ucvector_cleanup(), ucvector_init(), and ucvector_resize().

Referenced by ExpressionParser::parseFilter(), ExpressionParser::parseFilteredVariable(), preProcessScanlines(), readCodeFragment(), and readInputFile().

{
/*
For PNG filter method 0
out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline
There is a nice heuristic described here: http://www.cs.toronto.edu/~cosmin/pngtech/optipng.html. It says:
* If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None).
* (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row.
Here the above method is used mostly. Note though that it appears to be better to use the adaptive filtering on the plasma 8-bit palette example, but that image isn't the best reference for palette images in general.
*/
unsigned bpp = LodePNG_InfoColor_getBpp(info);
size_t linebytes = (w * bpp + 7) / 8; /*the width of a scanline in bytes, not including the filter type*/
size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
const unsigned char* prevline = 0;
unsigned x, y;
unsigned heuristic;
unsigned error = 0;
if(bpp == 0) return 31; /*invalid color type*/
/*choose heuristic as described above*/
if(info->colorType == 3 || info->bitDepth < 8) heuristic = 0;
else heuristic = 1;
if(heuristic == 0) /*None filtertype for everything*/
{
for(y = 0; y < h; y++)
{
size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
size_t inindex = linebytes * y;
const unsigned TYPE = 0;
out[outindex] = TYPE; /*filter type byte*/
filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, TYPE);
prevline = &in[inindex];
}
}
else if(heuristic == 1) /*adaptive filtering*/
{
size_t sum[5];
ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
size_t smallest = 0;
unsigned type, bestType = 0;
for(type = 0; type < 5; type++) ucvector_init(&attempt[type]);
for(type = 0; type < 5; type++)
{
if(!ucvector_resize(&attempt[type], linebytes)) { error = 9949; break; }
}
if(!error)
{
for(y = 0; y < h; y++)
{
/*try the 5 filter types*/
for(type = 0; type < 5; type++)
{
filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
/*calculate the sum of the result*/
sum[type] = 0;
for(x = 0; x < attempt[type].size; x+=3) sum[type] += attempt[type].data[x]; /*note that not all pixels are checked to speed this up while still having probably the best choice*/
/*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
if(type == 0 || sum[type] < smallest)
{
bestType = type;
smallest = sum[type];
}
}
prevline = &in[y * linebytes];
/*now fill the out values*/
out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
}
}
for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
}
#if 0 /*deflate the scanline with a fixed tree after every filter attempt to see which one deflates best. This is slow, and _does not work as expected_: the heuristic gives smaller result!*/
else if(heuristic == 2) /*adaptive filtering by using deflate*/
{
size_t size[5];
ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
size_t smallest;
unsigned type = 0, bestType = 0;
unsigned char* dummy;
deflatesettings.btype = 1; /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image*/
for(type = 0; type < 5; type++) { ucvector_init(&attempt[type]); ucvector_resize(&attempt[type], linebytes); }
for(y = 0; y < h; y++) /*try the 5 filter types*/
{
for(type = 0; type < 5; type++)
{
filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
size[type] = 0; dummy = 0;
LodePNG_compress(&dummy, &size[type], attempt[type].data, attempt[type].size, &deflatesettings);
free(dummy);
/*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
if(type == 0 || size[type] < smallest) { bestType = type; smallest = size[type]; }
}
prevline = &in[y * linebytes];
out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
}
for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
}
#endif
return error;
}
static void filterScanline ( unsigned char *  out,
const unsigned char *  scanline,
const unsigned char *  prevline,
size_t  length,
size_t  bytewidth,
unsigned char  filterType 
)
static

Definition at line 3532 of file lodepng.cpp.

References paethPredictor().

Referenced by filter().

{
size_t i;
switch(filterType)
{
case 0:
for(i = 0; i < length; i++) out[i] = scanline[i];
break;
case 1:
for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
break;
case 2:
if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i];
else for(i = 0; i < length; i++) out[i] = scanline[i];
break;
case 3:
if(prevline)
{
for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2;
for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
}
else
{
for(i = 0; i < length; i++) out[i] = scanline[i];
for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
}
break;
case 4:
if(prevline)
{
for(i = 0; i < bytewidth; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(0, prevline[i], 0));
for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
}
else
{
for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
for(i = bytewidth; i < length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], 0, 0));
}
break;
default: return; /*unexisting filter type given*/
}
}
static unsigned generateDistanceTree ( HuffmanTree tree)
static

Definition at line 668 of file lodepng.cpp.

References uivector::data, HuffmanTree_makeFromLengths(), NUM_DISTANCE_SYMBOLS, uivector_cleanup(), uivector_init(), and uivector_resize().

Referenced by deflateFixed().

{
unsigned i, error = 0;
uivector bitlen;
uivector_init(&bitlen);
if(!uivector_resize(&bitlen, NUM_DISTANCE_SYMBOLS)) error = 9910;
/*there are 32 distance codes, but 30-31 are unused*/
if(!error)
{
for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen.data[i] = 5;
error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DISTANCE_SYMBOLS, 15);
}
uivector_cleanup(&bitlen);
return error;
}
static unsigned generateFixedTree ( HuffmanTree tree)
static

Definition at line 646 of file lodepng.cpp.

References uivector::data, HuffmanTree_makeFromLengths(), NUM_DEFLATE_CODE_SYMBOLS, uivector_cleanup(), uivector_init(), and uivector_resize().

Referenced by deflateFixed().

{
unsigned i, error = 0;
uivector bitlen;
uivector_init(&bitlen);
if(!uivector_resize(&bitlen, NUM_DEFLATE_CODE_SYMBOLS)) error = 9909;
if(!error)
{
/*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/
for(i = 0; i <= 143; i++) bitlen.data[i] = 8;
for(i = 144; i <= 255; i++) bitlen.data[i] = 9;
for(i = 256; i <= 279; i++) bitlen.data[i] = 7;
for(i = 280; i <= 287; i++) bitlen.data[i] = 8;
}
uivector_cleanup(&bitlen);
return error;
}
static unsigned getBpp ( unsigned  colorType,
unsigned  bitDepth 
)
static

Definition at line 2018 of file lodepng.cpp.

References getNumColorChannels().

Referenced by LodePNG_InfoColor_getBpp().

{
return getNumColorChannels(colorType) * bitDepth; /*bits per pixel is amount of channels * bits per channel*/
}
static unsigned getNumColorChannels ( unsigned  colorType)
static

Definition at line 2005 of file lodepng.cpp.

Referenced by getBpp(), and LodePNG_InfoColor_getChannels().

{
switch(colorType)
{
case 0: return 1; /*grey*/
case 2: return 3; /*RGB*/
case 3: return 1; /*palette*/
case 4: return 2; /*grey + alpha*/
case 6: return 4; /*RGBA*/
}
return 0; /*unexisting color type*/
}
static void HuffmanTree_cleanup ( HuffmanTree tree)
static
static unsigned HuffmanTree_fillInCoins ( vector coins,
const unsigned *  frequencies,
unsigned  numcodes,
size_t  sum 
)
static

Definition at line 538 of file lodepng.cpp.

References Coin_init(), Coin_sort(), vector::data, vector::size, Coin::symbols, uivector_push_back(), vector_cleanup(), vector_get(), vector_resize(), and Coin::weight.

Referenced by HuffmanTree_makeFromFrequencies().

{
unsigned i;
for(i = 0; i < numcodes; i++)
{
Coin* coin;
if(frequencies[i] == 0) continue; /*it's important to exclude symbols that aren't present*/
if(!vector_resize(coins, coins->size + 1)) { vector_cleanup(coins); return 9904; }
coin = (Coin*)(vector_get(coins, coins->size - 1));
Coin_init(coin);
coin->weight = frequencies[i] / (float)sum;
}
if(coins->size) Coin_sort((Coin*)coins->data, coins->size);
return 0;
}
static unsigned HuffmanTree_getCode ( const HuffmanTree tree,
unsigned  index 
)
static

Definition at line 641 of file lodepng.cpp.

References uivector::data, and HuffmanTree::tree1d.

Referenced by deflateDynamic(), deflateFixed(), and writeLZ77data().

{ return tree->tree1d.data[index]; }
static unsigned HuffmanTree_getLength ( const HuffmanTree tree,
unsigned  index 
)
static

Definition at line 642 of file lodepng.cpp.

References uivector::data, and HuffmanTree::lengths.

Referenced by deflateDynamic(), deflateFixed(), and writeLZ77data().

{ return tree->lengths.data[index]; }
static void HuffmanTree_init ( HuffmanTree tree)
static
static unsigned HuffmanTree_make2DTree ( HuffmanTree tree)
static

Definition at line 459 of file lodepng.cpp.

References uivector::data, HuffmanTree::lengths, HuffmanTree::numcodes, HuffmanTree::tree1d, HuffmanTree::tree2d, and uivector_resize().

Referenced by HuffmanTree_makeFromLengths2().

{
unsigned nodefilled = 0; /*up to which node it is filled*/
unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/
unsigned n, i;
if(!uivector_resize(&tree->tree2d, tree->numcodes * 2)) return 9901; /*if failed return not enough memory error*/
/*convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1
a good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen*/
for(n = 0; n < tree->numcodes * 2; n++) tree->tree2d.data[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/
for(n = 0; n < tree->numcodes; n++) /*the codes*/
for(i = 0; i < tree->lengths.data[n]; i++) /*the bits for this code*/
{
unsigned char bit = (unsigned char)((tree->tree1d.data[n] >> (tree->lengths.data[n] - i - 1)) & 1);
if(treepos > tree->numcodes - 2) return 55; /*error 55: oversubscribed; see description in header*/
if(tree->tree2d.data[2 * treepos + bit] == 32767) /*not yet filled in*/
{
if(i + 1 == tree->lengths.data[n]) /*last bit*/
{
tree->tree2d.data[2 * treepos + bit] = n; /*put the current code in it*/
treepos = 0;
}
else /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/
{
nodefilled++;
tree->tree2d.data[2 * treepos + bit] = nodefilled + tree->numcodes; /*addresses encoded with numcodes added to it*/
treepos = nodefilled;
}
}
else treepos = tree->tree2d.data[2 * treepos + bit] - tree->numcodes;
}
for(n = 0; n < tree->numcodes * 2; n++) if(tree->tree2d.data[n] == 32767) tree->tree2d.data[n] = 0; /*remove possible remaining 32767's*/
return 0;
}
static unsigned HuffmanTree_makeFromFrequencies ( HuffmanTree tree,
const unsigned *  frequencies,
size_t  numcodes,
unsigned  maxbitlen 
)
static

Definition at line 555 of file lodepng.cpp.

References addCoins(), Coin_cleanup(), Coin_copy(), Coin_init(), uivector::data, HuffmanTree_fillInCoins(), HuffmanTree_makeFromLengths2(), HuffmanTree::lengths, HuffmanTree::maxbitlen, HuffmanTree::numcodes, vector::size, uivector::size, Coin::symbols, uivector_resize(), uivector_resizev(), vector_cleanupd(), vector_get(), vector_init(), vector_resize(), vector_resized(), and vector_swap().

Referenced by deflateDynamic().

{
unsigned i, j;
size_t sum = 0, numpresent = 0;
unsigned error = 0;
vector prev_row; /*type Coin, the previous row of coins*/
vector coins; /*type Coin, the coins of the currently calculated row*/
tree->maxbitlen = maxbitlen;
for(i = 0; i < numcodes; i++)
{
if(frequencies[i] > 0)
{
numpresent++;
sum += frequencies[i];
}
}
if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
tree->numcodes = (unsigned)numcodes; /*number of symbols*/
if(!uivector_resizev(&tree->lengths, tree->numcodes, 0)) return 9905;
if(numpresent == 0) /*there are no symbols at all, in that case add one symbol of value 0 to the tree (see RFC 1951 section 3.2.7) */
{
tree->lengths.data[0] = 1;
}
else if(numpresent == 1) /*the package merge algorithm gives wrong results if there's only one symbol (theoretically 0 bits would then suffice, but we need a proper symbol for zlib)*/
{
for(i = 0; i < numcodes; i++) if(frequencies[i]) tree->lengths.data[i] = 1;
}
vector_init(&coins, sizeof(Coin));
vector_init(&prev_row, sizeof(Coin));
/*Package-Merge algorithm represented by coin collector's problem
For every symbol, maxbitlen coins will be created*/
/*first row, lowest denominator*/
error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
if(!error)
{
for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/
{
vector_swap(&coins, &prev_row); /*swap instead of copying*/
if(!vector_resized(&coins, 0, Coin_cleanup)) { error = 9906; break; }
for(i = 0; i + 1 < prev_row.size; i += 2)
{
if(!vector_resize(&coins, coins.size + 1)) { error = 9907; break; }
Coin_init((Coin*)vector_get(&coins, coins.size - 1));
Coin_copy((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i));
addCoins((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i + 1)); /*merge the coins into packages*/
}
if(j < maxbitlen)
{
error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
}
}
}
if(!error)
{
/*keep the coins with lowest weight, so that they add up to the amount of symbols - 1*/
vector_resized(&coins, numpresent - 1, Coin_cleanup);
/*calculate the lengths of each symbol, as the amount of times a coin of each symbol is used*/
for(i = 0; i < coins.size; i++)
{
Coin* coin = (Coin*)vector_get(&coins, i);
for(j = 0; j < coin->symbols.size; j++) tree->lengths.data[coin->symbols.data[j]]++;
}
}
return error;
}
static unsigned HuffmanTree_makeFromLengths ( HuffmanTree tree,
const unsigned *  bitlen,
size_t  numcodes,
unsigned  maxbitlen 
)
static

Definition at line 527 of file lodepng.cpp.

References uivector::data, HuffmanTree_makeFromLengths2(), HuffmanTree::lengths, HuffmanTree::maxbitlen, HuffmanTree::numcodes, and uivector_resize().

Referenced by generateDistanceTree(), and generateFixedTree().

{
unsigned i;
if(!uivector_resize(&tree->lengths, numcodes)) return 9903;
for(i = 0; i < numcodes; i++) tree->lengths.data[i] = bitlen[i];
tree->numcodes = (unsigned)numcodes; /*number of symbols*/
tree->maxbitlen = maxbitlen;
}
static unsigned HuffmanTree_makeFromLengths2 ( HuffmanTree tree)
static

Definition at line 496 of file lodepng.cpp.

References uivector::data, HuffmanTree_make2DTree(), HuffmanTree::lengths, HuffmanTree::maxbitlen, HuffmanTree::numcodes, HuffmanTree::tree1d, uivector_cleanup(), uivector_init(), uivector_resize(), and uivector_resizev().

Referenced by HuffmanTree_makeFromFrequencies(), and HuffmanTree_makeFromLengths().

{
uivector blcount;
uivector nextcode;
unsigned bits, n, error = 0;
uivector_init(&blcount);
uivector_init(&nextcode);
if(!uivector_resize(&tree->tree1d, tree->numcodes)
|| !uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
|| !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
error = 9902;
if(!error)
{
/*step 1: count number of instances of each code length*/
for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths.data[bits]]++;
/*step 2: generate the nextcode values*/
for(bits = 1; bits <= tree->maxbitlen; bits++) nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
/*step 3: generate all the codes*/
for(n = 0; n < tree->numcodes; n++) if(tree->lengths.data[n] != 0) tree->tree1d.data[n] = nextcode.data[tree->lengths.data[n]]++;
}
uivector_cleanup(&blcount);
uivector_cleanup(&nextcode);
if(!error) return HuffmanTree_make2DTree(tree);
else return error;
}
static unsigned isFullyOpaque ( const unsigned char *  image,
unsigned  w,
unsigned  h,
const LodePNG_InfoColor info 
)
static

Definition at line 3857 of file lodepng.cpp.

References LodePNG_InfoColor::bitDepth, LodePNG_InfoColor::colorType, isPaletteFullyOpaque(), LodePNG_InfoColor::palette, and LodePNG_InfoColor::palettesize.

Referenced by LodePNG_encode().

{
/*TODO: When the user specified a color key for the input image, then this function must also check for pixels that are the same as the color key and treat those as transparent.*/
unsigned i, numpixels = w * h;
if(info->colorType == 6)
{
if(info->bitDepth == 8)
{
for(i = 0; i < numpixels; i++) if(image[i * 4 + 3] != 255) return 0;
}
else
{
for(i = 0; i < numpixels; i++) if(image[i * 8 + 6] != 255 || image[i * 8 + 7] != 255) return 0;
}
return 1; /*no single pixel with alpha channel other than 255 found*/
}
else if(info->colorType == 4)
{
if(info->bitDepth == 8)
{
for(i = 0; i < numpixels; i++) if(image[i * 2 + 1] != 255) return 0;
}
else
{
for(i = 0; i < numpixels; i++) if(image[i * 4 + 2] != 255 || image[i * 4 + 3] != 255) return 0;
}
return 1; /*no single pixel with alpha channel other than 255 found*/
}
else if(info->colorType == 3)
{
/*when there's a palette, we could check every pixel for translucency, but much quicker is to just check the palette*/
return(isPaletteFullyOpaque(info->palette, info->palettesize));
}
return 0; /*color type that isn't supported by this function yet, so assume there is transparency to be safe*/
}
static unsigned isPaletteFullyOpaque ( const unsigned char *  palette,
size_t  palettesize 
)
static

Definition at line 3846 of file lodepng.cpp.

Referenced by isFullyOpaque(), and LodePNG_encode().

{
size_t i;
for(i = 0; i < palettesize; i++)
{
if(palette[4 * i + 3] != 255) return 0;
}
return 1;
}
unsigned LodeFlate_deflate ( ucvector out,
const unsigned char *  data,
size_t  datasize,
const LodeZlib_DeflateSettings settings 
)

Definition at line 1542 of file lodepng.cpp.

References LodeZlib_DeflateSettings::btype, deflateDynamic(), deflateFixed(), and deflateNoCompression().

Referenced by LodeZlib_compress().

{
unsigned error = 0;
if(settings->btype == 0) error = deflateNoCompression(out, data, datasize);
else if(settings->btype == 1) error = deflateFixed(out, data, datasize, settings);
else if(settings->btype == 2) error = deflateDynamic(out, data, datasize, settings);
else error = 61;
return error;
}
static void LodePNG_add32bitInt ( ucvector buffer,
unsigned  value 
)
static

Definition at line 1854 of file lodepng.cpp.

References ucvector::data, LodePNG_set32bitInt(), ucvector::size, and ucvector_resize().

Referenced by addChunk_IHDR().

{
ucvector_resize(buffer, buffer->size + 4);
LodePNG_set32bitInt(&buffer->data[buffer->size - 4], value);
}
unsigned LodePNG_append_chunk ( unsigned char **  out,
size_t *  outlength,
const unsigned char *  chunk 
)

Definition at line 1937 of file lodepng.cpp.

References LodePNG_chunk_length().

{
unsigned i;
unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
unsigned char *chunk_start, *new_buffer;
size_t new_length = (*outlength) + total_chunk_length;
if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/
new_buffer = (unsigned char*)realloc(*out, new_length);
if(!new_buffer) return 9929;
(*out) = new_buffer;
(*outlength) = new_length;
chunk_start = &(*out)[new_length - total_chunk_length];
for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i];
return 0;
}
unsigned LodePNG_chunk_check_crc ( const unsigned char *  chunk)

Definition at line 1909 of file lodepng.cpp.

References Crc32_crc(), LodePNG_chunk_length(), and LodePNG_read32bitInt().

{
unsigned length = LodePNG_chunk_length(chunk);
unsigned CRC = LodePNG_read32bitInt(&chunk[length + 8]);
unsigned checksum = Crc32_crc(&chunk[4], length + 4); /*the CRC is taken of the data and the 4 chunk type letters, not the length*/
if(CRC != checksum) return 1;
else return 0;
}
unsigned char LodePNG_chunk_critical ( const unsigned char *  chunk)

Definition at line 1884 of file lodepng.cpp.

{
return((chunk[4] & 32) == 0);
}
unsigned char* LodePNG_chunk_data ( unsigned char *  chunk)

Definition at line 1899 of file lodepng.cpp.

{
return &chunk[8];
}
const unsigned char* LodePNG_chunk_data_const ( const unsigned char *  chunk)

Definition at line 1904 of file lodepng.cpp.

{
return &chunk[8];
}
void LodePNG_chunk_generate_crc ( unsigned char *  chunk)

Definition at line 1918 of file lodepng.cpp.

References Crc32_crc(), LodePNG_chunk_length(), and LodePNG_set32bitInt().

Referenced by LodePNG_create_chunk().

{
unsigned length = LodePNG_chunk_length(chunk);
unsigned CRC = Crc32_crc(&chunk[4], length + 4);
LodePNG_set32bitInt(chunk + 8 + length, CRC);
}
unsigned LodePNG_chunk_length ( const unsigned char *  chunk)
unsigned char* LodePNG_chunk_next ( unsigned char *  chunk)

Definition at line 1925 of file lodepng.cpp.

References LodePNG_chunk_length().

{
unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
return &chunk[total_chunk_length];
}
const unsigned char* LodePNG_chunk_next_const ( const unsigned char *  chunk)

Definition at line 1931 of file lodepng.cpp.

References LodePNG_chunk_length().

{
unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
return &chunk[total_chunk_length];
}
unsigned char LodePNG_chunk_private ( const unsigned char *  chunk)

Definition at line 1889 of file lodepng.cpp.

{
return((chunk[6] & 32) != 0);
}
unsigned char LodePNG_chunk_safetocopy ( const unsigned char *  chunk)

Definition at line 1894 of file lodepng.cpp.

{
return((chunk[7] & 32) != 0);
}
void LodePNG_chunk_type ( char  type[5],
const unsigned char *  chunk 
)

Definition at line 1870 of file lodepng.cpp.

{
unsigned i;
for(i = 0; i < 4; i++) type[i] = chunk[4 + i];
type[4] = 0; /*null termination char*/
}
unsigned char LodePNG_chunk_type_equals ( const unsigned char *  chunk,
const char *  type 
)

Definition at line 1877 of file lodepng.cpp.

{
if(strlen(type) != 4) return 0;
return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
}
static unsigned LodePNG_compress ( unsigned char **  out,
size_t *  outsize,
const unsigned char *  in,
size_t  insize,
const LodeZlib_DeflateSettings settings 
)
static

Definition at line 1752 of file lodepng.cpp.

References LodeZlib_compress().

Referenced by addChunk_IDAT(), and filter().

{
return LodeZlib_compress(out, outsize, in, insize, settings);
}
unsigned LodePNG_convert ( unsigned char *  out,
const unsigned char *  in,
LodePNG_InfoColor infoOut,
LodePNG_InfoColor infoIn,
unsigned  w,
unsigned  h 
)

Definition at line 2361 of file lodepng.cpp.

References LodePNG_InfoColor::bitDepth, LodePNG_InfoColor::colorType, LodePNG_InfoColor::key_b, LodePNG_InfoColor::key_defined, LodePNG_InfoColor::key_g, LodePNG_InfoColor::key_r, LodePNG_InfoColor_equal(), LodePNG_InfoColor_getBpp(), LodePNG_InfoColor_isAlphaType(), LodePNG_InfoColor_isGreyscaleType(), LodePNG_InfoColor::palette, LodePNG_InfoColor::palettesize, and readBitsFromReversedStream().

Referenced by LodePNG_encode().

{
const size_t numpixels = w * h; /*amount of pixels*/
const unsigned OUT_BYTES = LodePNG_InfoColor_getBpp(infoOut) / 8; /*bytes per pixel in the output image*/
const unsigned OUT_ALPHA = LodePNG_InfoColor_isAlphaType(infoOut); /*use 8-bit alpha channel*/
size_t i, c, bp = 0; /*bitpointer, used by less-than-8-bit color types*/
/*cases where in and out already have the same format*/
if(LodePNG_InfoColor_equal(infoIn, infoOut))
{
size_t i, size = (w * h * LodePNG_InfoColor_getBpp(infoIn) + 7) / 8;
for(i = 0; i < size; i++) out[i] = in[i];
return 0;
}
if((infoOut->colorType == 2 || infoOut->colorType == 6) && infoOut->bitDepth == 8)
{
if(infoIn->bitDepth == 8)
{
switch(infoIn->colorType)
{
case 0: /*greyscale color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[i];
if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
}
break;
case 2: /*RGB color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[3 * i + c];
if(OUT_ALPHA && infoIn->key_defined == 1 && in[3 * i + 0] == infoIn->key_r && in[3 * i + 1] == infoIn->key_g && in[3 * i + 2] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
}
break;
case 3: /*indexed color (palette)*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
if(in[i] >= infoIn->palettesize) return 46;
for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * in[i] + c]; /*get rgb colors from the palette*/
}
break;
case 4: /*greyscale with alpha*/
for(i = 0; i < numpixels; i++)
{
out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i + 0];
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[2 * i + 1];
}
break;
case 6: /*RGB with alpha*/
for(i = 0; i < numpixels; i++)
{
for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[4 * i + c];
}
break;
default: break;
}
}
else if(infoIn->bitDepth == 16)
{
switch(infoIn->colorType)
{
case 0: /*greyscale color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i];
if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
}
break;
case 2: /*RGB color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[6 * i + 2 * c];
if(OUT_ALPHA && infoIn->key_defined && 256U * in[6 * i + 0] + in[6 * i + 1] == infoIn->key_r && 256U * in[6 * i + 2] + in[6 * i + 3] == infoIn->key_g && 256U * in[6 * i + 4] + in[6 * i + 5] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
}
break;
case 4: /*greyscale with alpha*/
for(i = 0; i < numpixels; i++)
{
out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[4 * i]; /*most significant byte*/
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[4 * i + 2];
}
break;
case 6: /*RGB with alpha*/
for(i = 0; i < numpixels; i++)
{
for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[8 * i + 2 * c];
}
break;
default: break;
}
}
else /*infoIn->bitDepth is less than 8 bit per channel*/
{
switch(infoIn->colorType)
{
case 0: /*greyscale color*/
for(i = 0; i < numpixels; i++)
{
unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 3] = 0;
value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = (unsigned char)(value);
}
break;
case 3: /*indexed color (palette)*/
for(i = 0; i < numpixels; i++)
{
unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
if(value >= infoIn->palettesize) return 47;
for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * value + c]; /*get rgb colors from the palette*/
}
break;
default: break;
}
}
}
else if(LodePNG_InfoColor_isGreyscaleType(infoOut) && infoOut->bitDepth == 8) /*conversion from greyscale to greyscale*/
{
if(!LodePNG_InfoColor_isGreyscaleType(infoIn)) return 62;
if(infoIn->bitDepth == 8)
{
switch(infoIn->colorType)
{
case 0: /*greyscale color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
out[OUT_BYTES * i] = in[i];
if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
}
break;
case 4: /*greyscale with alpha*/
for(i = 0; i < numpixels; i++)
{
out[OUT_BYTES * i + 0] = in[2 * i + 0];
if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[2 * i + 1];
}
break;
default: return 31;
}
}
else if(infoIn->bitDepth == 16)
{
switch(infoIn->colorType)
{
case 0: /*greyscale color*/
for(i = 0; i < numpixels; i++)
{
if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
out[OUT_BYTES * i] = in[2 * i];
if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
}
break;
case 4: /*greyscale with alpha*/
for(i = 0; i < numpixels; i++)
{
out[OUT_BYTES * i] = in[4 * i]; /*most significant byte*/
if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[4 * i + 2]; /*most significant byte*/
}
break;
default: return 31;
}
}
else /*infoIn->bitDepth is less than 8 bit per channel*/
{
if(infoIn->colorType != 0) return 31; /*colorType 0 is the only greyscale type with < 8 bits per channel*/
for(i = 0; i < numpixels; i++)
{
unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 1] = 0;
value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
out[OUT_BYTES * i] = (unsigned char)(value);
}
}
}
else return 59;
return 0;
}
unsigned LodePNG_create_chunk ( unsigned char **  out,
size_t *  outlength,
unsigned  length,
const char *  type,
const unsigned char *  data 
)

Definition at line 1956 of file lodepng.cpp.

References LodePNG_chunk_generate_crc(), and LodePNG_set32bitInt().

Referenced by addChunk().

{
unsigned i;
unsigned char *chunk, *new_buffer;
size_t new_length = (*outlength) + length + 12;
if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/
new_buffer = (unsigned char*)realloc(*out, new_length);
if(!new_buffer) return 9930;
(*out) = new_buffer;
(*outlength) = new_length;
chunk = &(*out)[(*outlength) - length - 12];
/*1: length*/
LodePNG_set32bitInt(chunk, (unsigned)length);
/*2: chunk name (4 letters)*/
chunk[4] = type[0];
chunk[5] = type[1];
chunk[6] = type[2];
chunk[7] = type[3];
/*3: the data*/
for(i = 0; i < length; i++) chunk[8 + i] = data[i];
/*4: CRC (of the chunkname characters and the data)*/
return 0;
}
void LodePNG_encode ( LodePNG_Encoder encoder,
unsigned char **  out,
size_t *  outsize,
const unsigned char *  image,
unsigned  w,
unsigned  h 
)

Definition at line 3910 of file lodepng.cpp.

References addChunk_IDAT(), addChunk_IEND(), addChunk_IHDR(), addChunk_PLTE(), addChunk_tRNS(), LodePNG_EncodeSettings::autoLeaveOutAlphaChannel, LodePNG_InfoColor::bitDepth, LodeZlib_DeflateSettings::btype, checkColorValidity(), LodePNG_InfoPng::color, LodePNG_InfoRaw::color, LodePNG_InfoColor::colorType, ucvector::data, LodePNG_Encoder::error, LodePNG_EncodeSettings::force_palette, LodePNG_InfoPng::height, LodePNG_Encoder::infoPng, LodePNG_Encoder::infoRaw, LodePNG_InfoPng::interlaceMethod, isFullyOpaque(), isPaletteFullyOpaque(), LodePNG_InfoColor::key_defined, LodePNG_convert(), LodePNG_InfoColor_equal(), LodePNG_InfoColor_getBpp(), LodePNG_InfoColor::palette, LodePNG_InfoColor::palettesize, preProcessScanlines(), LodePNG_Encoder::settings, ucvector::size, ucvector_init(), VERSION_STRING, LodePNG_InfoPng::width, LodeZlib_DeflateSettings::windowSize, writeSignature(), and LodePNG_EncodeSettings::zlibsettings.

Referenced by LodePNG_encode32(), Image::save(), and ColoredImage::save().

{
ucvector outv;
unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/
size_t datasize = 0;
/*provide some proper output values if error will happen*/
*out = 0;
*outsize = 0;
encoder->error = 0;
info = encoder->infoPng; /*UNSAFE copy to avoid having to cleanup! but we will only change primitive parameters, and not invoke the cleanup function nor touch the palette's buffer so we use it safely*/
info.width = w;
info.height = h;
if(encoder->settings.autoLeaveOutAlphaChannel && isFullyOpaque(image, w, h, &encoder->infoRaw.color))
{
/*go to a color type without alpha channel*/
if(info.color.colorType == 6) info.color.colorType = 2;
else if(info.color.colorType == 4) info.color.colorType = 0;
}
if(encoder->settings.zlibsettings.windowSize > 32768) { encoder->error = 60; return; } /*error: windowsize larger than allowed*/
if(encoder->settings.zlibsettings.btype > 2) { encoder->error = 61; return; } /*error: unexisting btype*/
if(encoder->infoPng.interlaceMethod > 1) { encoder->error = 71; return; } /*error: unexisting interlace mode*/
if((encoder->error = checkColorValidity(info.color.colorType, info.color.bitDepth))) return; /*error: unexisting color type given*/
if((encoder->error = checkColorValidity(encoder->infoRaw.color.colorType, encoder->infoRaw.color.bitDepth))) return; /*error: unexisting color type given*/
if(!LodePNG_InfoColor_equal(&encoder->infoRaw.color, &info.color))
{
unsigned char* converted;
size_t size = (w * h * LodePNG_InfoColor_getBpp(&info.color) + 7) / 8;
if((info.color.colorType != 6 && info.color.colorType != 2) || (info.color.bitDepth != 8)) { encoder->error = 59; return; } /*for the output image, only these types are supported*/
converted = (unsigned char*)malloc(size);
if(!converted && size) encoder->error = 9955; /*error: malloc failed*/
if(!encoder->error) encoder->error = LodePNG_convert(converted, image, &info.color, &encoder->infoRaw.color, w, h);
if(!encoder->error) preProcessScanlines(&data, &datasize, converted, &info);/*filter(data.data, converted.data, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
free(converted);
}
else preProcessScanlines(&data, &datasize, image, &info);/*filter(data.data, image, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
ucvector_init(&outv);
while(!encoder->error) /*not really a while loop, this is only used to break out if an error happens to avoid goto's to do the ucvector cleanup*/
{
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
size_t i;
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*write signature and chunks*/
/*IHDR*/
addChunk_IHDR(&outv, w, h, info.color.bitDepth, info.color.colorType, info.interlaceMethod);
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
/*unknown chunks between IHDR and PLTE*/
if(info.unknown_chunks.data[0]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[0], info.unknown_chunks.datasize[0]); if(encoder->error) break; }
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
/*PLTE*/
if(info.color.colorType == 3)
{
if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
addChunk_PLTE(&outv, &info.color);
}
if(encoder->settings.force_palette && (info.color.colorType == 2 || info.color.colorType == 6))
{
if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
addChunk_PLTE(&outv, &info.color);
}
/*tRNS*/
if(info.color.colorType == 3 && !isPaletteFullyOpaque(info.color.palette, info.color.palettesize)) addChunk_tRNS(&outv, &info.color);
if((info.color.colorType == 0 || info.color.colorType == 2) && info.color.key_defined) addChunk_tRNS(&outv, &info.color);
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*bKGD (must come between PLTE and the IDAt chunks*/
if(info.background_defined) addChunk_bKGD(&outv, &info);
/*pHYs (must come before the IDAT chunks)*/
if(info.phys_defined) addChunk_pHYs(&outv, &info);
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
/*unknown chunks between PLTE and IDAT*/
if(info.unknown_chunks.data[1]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[1], info.unknown_chunks.datasize[1]); if(encoder->error) break; }
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
/*IDAT (multiple IDAT chunks must be consecutive)*/
encoder->error = addChunk_IDAT(&outv, data, datasize, &encoder->settings.zlibsettings);
if(encoder->error) break;
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*tIME*/
if(info.time_defined) addChunk_tIME(&outv, &info.time);
/*tEXt and/or zTXt*/
for(i = 0; i < info.text.num; i++)
{
if(strlen(info.text.keys[i]) > 79) { encoder->error = 66; break; }
if(strlen(info.text.keys[i]) < 1) { encoder->error = 67; break; }
if(encoder->settings.text_compression)
addChunk_zTXt(&outv, info.text.keys[i], info.text.strings[i], &encoder->settings.zlibsettings);
else
addChunk_tEXt(&outv, info.text.keys[i], info.text.strings[i]);
}
/*LodePNG version id in text chunk*/
if(encoder->settings.add_id)
{
unsigned alread_added_id_text = 0;
for(i = 0; i < info.text.num; i++)
if(!strcmp(info.text.keys[i], "LodePNG")) { alread_added_id_text = 1; break; }
if(alread_added_id_text == 0)
addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
}
/*iTXt*/
for(i = 0; i < info.itext.num; i++)
{
if(strlen(info.itext.keys[i]) > 79) { encoder->error = 66; break; }
if(strlen(info.itext.keys[i]) < 1) { encoder->error = 67; break; }
addChunk_iTXt(&outv, encoder->settings.text_compression,
info.itext.keys[i], info.itext.langtags[i], info.itext.transkeys[i], info.itext.strings[i],
&encoder->settings.zlibsettings);
}
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
/*unknown chunks between IDAT and IEND*/
if(info.unknown_chunks.data[2]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[2], info.unknown_chunks.datasize[2]); if(encoder->error) break; }
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
/*IEND*/
addChunk_IEND(&outv);
break; /*this isn't really a while loop; no error happened so break out now!*/
}
free(data);
/*instead of cleaning the vector up, give it to the output*/
*out = outv.data;
*outsize = outv.size;
}
unsigned LodePNG_encode32 ( unsigned char **  out,
size_t *  outsize,
const unsigned char *  image,
unsigned  w,
unsigned  h 
)

Definition at line 4042 of file lodepng.cpp.

References LodePNG_Encoder::error, LodePNG_encode(), LodePNG_Encoder_cleanup(), and LodePNG_Encoder_init().

Referenced by LodePNG_encode32f().

{
unsigned error;
LodePNG_Encoder encoder;
LodePNG_encode(&encoder, out, outsize, image, w, h);
error = encoder.error;
return error;
}
unsigned LodePNG_encode32f ( const char *  filename,
const unsigned char *  image,
unsigned  w,
unsigned  h 
)

Definition at line 4054 of file lodepng.cpp.

References LodePNG_encode32(), and LodePNG_saveFile().

{
unsigned char* buffer;
size_t buffersize;
unsigned error = LodePNG_encode32(&buffer, &buffersize, image, w, h);
LodePNG_saveFile(buffer, buffersize, filename);
free(buffer);
return error;
}
void LodePNG_Encoder_cleanup ( LodePNG_Encoder encoder)
void LodePNG_Encoder_copy ( LodePNG_Encoder dest,
const LodePNG_Encoder source 
)
void LodePNG_Encoder_init ( LodePNG_Encoder encoder)
void LodePNG_EncodeSettings_init ( LodePNG_EncodeSettings settings)

Definition at line 4065 of file lodepng.cpp.

References LodePNG_EncodeSettings::autoLeaveOutAlphaChannel, LodePNG_EncodeSettings::force_palette, LodeZlib_DeflateSettings_init(), and LodePNG_EncodeSettings::zlibsettings.

Referenced by LodePNG_Encoder_init().

{
settings->autoLeaveOutAlphaChannel = 1;
settings->force_palette = 0;
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
settings->add_id = 1;
settings->text_compression = 0;
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
}
unsigned LodePNG_InfoColor_addPalette ( LodePNG_InfoColor info,
unsigned char  r,
unsigned char  g,
unsigned char  b,
unsigned char  a 
)

Definition at line 2046 of file lodepng.cpp.

References LodePNG_InfoColor::palette, and LodePNG_InfoColor::palettesize.

Referenced by Image::save().

{
unsigned char* data;
/*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/
if(!(info->palettesize & (info->palettesize - 1))) /*if palettesize is 0 or a power of two*/
{
/*allocated data must be at least 4* palettesize (for 4 color bytes)*/
size_t alloc_size = info->palettesize == 0 ? 4 : info->palettesize * 4 * 2;
data = (unsigned char*)realloc(info->palette, alloc_size);
if(!data) return 9931;
else info->palette = data;
}
info->palette[4 * info->palettesize + 0] = r;
info->palette[4 * info->palettesize + 1] = g;
info->palette[4 * info->palettesize + 2] = b;
info->palette[4 * info->palettesize + 3] = a;
info->palettesize++;
return 0;
}
void LodePNG_InfoColor_cleanup ( LodePNG_InfoColor info)
void LodePNG_InfoColor_clearPalette ( LodePNG_InfoColor info)

Definition at line 2040 of file lodepng.cpp.

References LodePNG_InfoColor::palette, and LodePNG_InfoColor::palettesize.

Referenced by LodePNG_InfoColor_cleanup().

{
if(info->palette) free(info->palette);
info->palettesize = 0;
}
unsigned LodePNG_InfoColor_copy ( LodePNG_InfoColor dest,
const LodePNG_InfoColor source 
)

Definition at line 2323 of file lodepng.cpp.

References LodePNG_InfoColor_cleanup(), LodePNG_InfoColor::palette, and LodePNG_InfoColor::palettesize.

Referenced by LodePNG_InfoPng_copy(), and LodePNG_InfoRaw_copy().

{
size_t i;
*dest = *source;
dest->palette = (unsigned char*)malloc(source->palettesize * 4);
if(!dest->palette && source->palettesize) return 9935;
for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i];
return 0;
}
unsigned LodePNG_InfoColor_equal ( const LodePNG_InfoColor info1,
const LodePNG_InfoColor info2 
)

Definition at line 2071 of file lodepng.cpp.

References LodePNG_InfoColor::bitDepth, and LodePNG_InfoColor::colorType.

Referenced by LodePNG_convert(), and LodePNG_encode().

{
return info1->colorType == info2->colorType
&& info1->bitDepth == info2->bitDepth; /*palette and color key not compared*/
}
unsigned LodePNG_InfoColor_getBpp ( const LodePNG_InfoColor info)

Definition at line 2066 of file lodepng.cpp.

References LodePNG_InfoColor::bitDepth, LodePNG_InfoColor::colorType, and getBpp().

Referenced by filter(), LodePNG_convert(), LodePNG_encode(), and preProcessScanlines().

{ return getBpp(info->colorType, info->bitDepth); } /*calculate bits per pixel out of colorType and bitDepth*/
unsigned LodePNG_InfoColor_getChannels ( const LodePNG_InfoColor info)

Definition at line 2067 of file lodepng.cpp.

References LodePNG_InfoColor::colorType, and getNumColorChannels().

{ return getNumColorChannels(info->colorType); }
void LodePNG_InfoColor_init ( LodePNG_InfoColor info)
unsigned LodePNG_InfoColor_isAlphaType ( const LodePNG_InfoColor info)

Definition at line 2069 of file lodepng.cpp.

References LodePNG_InfoColor::colorType.

Referenced by LodePNG_convert().

{ return (info->colorType & 4) != 0; }
unsigned LodePNG_InfoColor_isGreyscaleType ( const LodePNG_InfoColor info)

Definition at line 2068 of file lodepng.cpp.

References LodePNG_InfoColor::colorType.

Referenced by LodePNG_convert().

{ return info->colorType == 0 || info->colorType == 4; }
void LodePNG_InfoPng_cleanup ( LodePNG_InfoPng info)

Definition at line 2284 of file lodepng.cpp.

References LodePNG_InfoPng::color, and LodePNG_InfoColor_cleanup().

Referenced by LodePNG_Encoder_cleanup(), and LodePNG_InfoPng_copy().

{
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
LodePNG_Text_cleanup(&info->text);
LodePNG_IText_cleanup(&info->itext);
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
LodePNG_UnknownChunks_cleanup(&info->unknown_chunks);
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
}
unsigned LodePNG_InfoPng_copy ( LodePNG_InfoPng dest,
const LodePNG_InfoPng source 
)

Definition at line 2296 of file lodepng.cpp.

References LodePNG_InfoPng::color, LodePNG_InfoColor_copy(), LodePNG_InfoColor_init(), and LodePNG_InfoPng_cleanup().

Referenced by LodePNG_Encoder_copy().

{
unsigned error = 0;
*dest = *source;
error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error;
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
error = LodePNG_Text_copy(&dest->text, &source->text); if(error) return error;
error = LodePNG_IText_copy(&dest->itext, &source->itext); if(error) return error;
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
LodePNG_UnknownChunks_init(&dest->unknown_chunks);
error = LodePNG_UnknownChunks_copy(&dest->unknown_chunks, &source->unknown_chunks); if(error) return error;
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
return error;
}
void LodePNG_InfoPng_init ( LodePNG_InfoPng info)

Definition at line 2262 of file lodepng.cpp.

References LodePNG_InfoPng::color, LodePNG_InfoPng::compressionMethod, LodePNG_InfoPng::filterMethod, LodePNG_InfoPng::height, LodePNG_InfoPng::interlaceMethod, LodePNG_InfoColor_init(), and LodePNG_InfoPng::width.

Referenced by LodePNG_Encoder_copy(), and LodePNG_Encoder_init().

{
info->width = info->height = 0;
info->interlaceMethod = 0;
info->compressionMethod = 0;
info->filterMethod = 0;
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
info->background_defined = 0;
info->background_r = info->background_g = info->background_b = 0;
LodePNG_Text_init(&info->text);
LodePNG_IText_init(&info->itext);
info->time_defined = 0;
info->phys_defined = 0;
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
LodePNG_UnknownChunks_init(&info->unknown_chunks);
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
}
void LodePNG_InfoPng_swap ( LodePNG_InfoPng a,
LodePNG_InfoPng b 
)

Definition at line 2316 of file lodepng.cpp.

{
LodePNG_InfoPng temp = *a;
*a = *b;
*b = temp;
}
void LodePNG_InfoRaw_cleanup ( LodePNG_InfoRaw info)
unsigned LodePNG_InfoRaw_copy ( LodePNG_InfoRaw dest,
const LodePNG_InfoRaw source 
)

Definition at line 2344 of file lodepng.cpp.

References LodePNG_InfoRaw::color, LodePNG_InfoColor_copy(), LodePNG_InfoColor_init(), and LodePNG_InfoRaw_cleanup().

Referenced by LodePNG_Encoder_copy().

{
unsigned error = 0;
*dest = *source;
error = LodePNG_InfoColor_copy(&dest->color, &source->color);
return error;
}
void LodePNG_InfoRaw_init ( LodePNG_InfoRaw info)
unsigned LodePNG_loadFile ( unsigned char **  out,
size_t *  outsize,
const char *  filename 
)

Definition at line 4110 of file lodepng.cpp.

References portable_fopen().

{
FILE* file;
long size;
/*provide some proper output values if error will happen*/
*out = 0;
*outsize = 0;
file = portable_fopen(filename, "rb");
if(!file) return 78;
/*get filesize:*/
fseek(file , 0 , SEEK_END);
size = ftell(file);
rewind(file);
/*read contents of the file into the vector*/
if (size>0)
{
*outsize = 0;
*out = (unsigned char*)malloc((size_t)size);
if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file);
}
fclose(file);
if(!(*out) && size) return 80; /*the above malloc failed*/
return 0;
}
static unsigned LodePNG_read32bitInt ( const unsigned char *  buffer)
static

Definition at line 1840 of file lodepng.cpp.

Referenced by LodePNG_chunk_check_crc(), and LodePNG_chunk_length().

{
return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
}
unsigned LodePNG_saveFile ( const unsigned char *  buffer,
size_t  buffersize,
const char *  filename 
)

Definition at line 4141 of file lodepng.cpp.

References portable_fopen().

Referenced by LodePNG_encode32f(), Image::save(), and ColoredImage::save().

{
FILE* file;
file = portable_fopen(filename, "wb" );
if(!file) return 79;
fwrite((char*)buffer , 1 , buffersize, file);
fclose(file);
return 0;
}
static void LodePNG_set32bitInt ( unsigned char *  buffer,
unsigned  value 
)
static

Definition at line 1845 of file lodepng.cpp.

Referenced by LodePNG_add32bitInt(), LodePNG_chunk_generate_crc(), and LodePNG_create_chunk().

{
buffer[0] = (unsigned char)((value >> 24) & 0xff);
buffer[1] = (unsigned char)((value >> 16) & 0xff);
buffer[2] = (unsigned char)((value >> 8) & 0xff);
buffer[3] = (unsigned char)((value ) & 0xff);
}
void LodeZlib_add32bitInt ( ucvector buffer,
unsigned  value 
)

Definition at line 1592 of file lodepng.cpp.

References ucvector_push_back().

Referenced by LodeZlib_compress().

{
ucvector_push_back(buffer, (unsigned char)((value >> 24) & 0xff));
ucvector_push_back(buffer, (unsigned char)((value >> 16) & 0xff));
ucvector_push_back(buffer, (unsigned char)((value >> 8) & 0xff));
ucvector_push_back(buffer, (unsigned char)((value ) & 0xff));
}
unsigned LodeZlib_compress ( unsigned char **  out,
size_t *  outsize,
const unsigned char *  in,
size_t  insize,
const LodeZlib_DeflateSettings settings 
)

Definition at line 1651 of file lodepng.cpp.

References adler32(), ucvector::data, LodeFlate_deflate(), LodeZlib_add32bitInt(), ucvector::size, ucvector_cleanup(), ucvector_init(), ucvector_init_buffer(), and ucvector_push_back().

Referenced by LodePNG_compress().

{
/*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/
ucvector deflatedata, outv;
size_t i;
unsigned error;
unsigned ADLER32;
/*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
unsigned FLEVEL = 0;
unsigned FDICT = 0;
unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
unsigned FCHECK = 31 - CMFFLG % 31;
CMFFLG += FCHECK;
ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/
ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256));
ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256));
ucvector_init(&deflatedata);
error = LodeFlate_deflate(&deflatedata, in, insize, settings);
if(!error)
{
ADLER32 = adler32(in, (unsigned)insize);
for(i = 0; i < deflatedata.size; i++) ucvector_push_back(&outv, deflatedata.data[i]);
ucvector_cleanup(&deflatedata);
LodeZlib_add32bitInt(&outv, ADLER32);
}
*out = outv.data;
*outsize = outv.size;
return error;
}
void LodeZlib_DeflateSettings_init ( LodeZlib_DeflateSettings settings)

Definition at line 1697 of file lodepng.cpp.

References LodeZlib_DeflateSettings::btype, LodeZlib_DeflateSettings::useLZ77, and LodeZlib_DeflateSettings::windowSize.

Referenced by LodePNG_EncodeSettings_init().

{
settings->btype = 2; /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/
settings->useLZ77 = 1;
settings->windowSize = 2048; /*this is a good tradeoff between speed and compression ratio*/
}
unsigned LodeZlib_read32bitInt ( const unsigned char *  buffer)

Definition at line 1601 of file lodepng.cpp.

{
return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
}
static int paethPredictor ( int  a,
int  b,
int  c 
)
static

Definition at line 2551 of file lodepng.cpp.

Referenced by filterScanline().

{
int p = a + b - c;
int pa = p > a ? p - a : a - p;
int pb = p > b ? p - b : b - p;
int pc = p > c ? p - c : c - p;
if(pa <= pb && pa <= pc) return a;
else if(pb <= pc) return b;
else return c;
}
static unsigned preProcessScanlines ( unsigned char **  out,
size_t *  outsize,
const unsigned char *  in,
const LodePNG_InfoPng infoPng 
)
static

Definition at line 3762 of file lodepng.cpp.

References Adam7_getpassvalues(), Adam7_interlace(), addPaddingBits(), LodePNG_InfoPng::color, ucvector::data, filter(), LodePNG_InfoPng::height, LodePNG_InfoPng::interlaceMethod, LodePNG_InfoColor_getBpp(), ucvector_cleanup(), ucvector_init(), ucvector_resize(), and LodePNG_InfoPng::width.

Referenced by LodePNG_encode().

{
/*
This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps:
*) if no Adam7: 1) add padding bits (= possible extra bits per scanline if bpp < 8) 2) filter
*) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter
*/
unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color);
unsigned w = infoPng->width;
unsigned h = infoPng->height;
unsigned error = 0;
if(infoPng->interlaceMethod == 0)
{
*outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/
*out = (unsigned char*)malloc(*outsize);
if(!(*out) && (*outsize)) error = 9950;
if(!error)
{
if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) /*non multiple of 8 bits per scanline, padding bits needed per scanline*/
{
ucvector padded;
ucvector_init(&padded);
if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9951;
if(!error)
{
addPaddingBits(padded.data, in, ((w * bpp + 7) / 8) * 8, w * bpp, h);
error = filter(*out, padded.data, w, h, &infoPng->color);
}
ucvector_cleanup(&padded);
}
else error = filter(*out, in, w, h, &infoPng->color); /*we can immediately filter into the out buffer, no other steps needed*/
}
}
else /*interlaceMethod is 1 (Adam7)*/
{
unsigned char* adam7 = (unsigned char*)malloc((h * w * bpp + 7) / 8);
if(!adam7 && ((h * w * bpp + 7) / 8)) error = 9952; /*malloc failed*/
while(!error) /*not a real while loop, used to break out to cleanup to avoid a goto*/
{
unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
unsigned i;
Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
*outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/
*out = (unsigned char*)malloc(*outsize);
if(!(*out) && (*outsize)) { error = 9953; break; }
Adam7_interlace(adam7, in, w, h, bpp);
for(i = 0; i < 7; i++)
{
if(bpp < 8)
{
ucvector padded;
ucvector_init(&padded);
if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9954;
if(!error)
{
addPaddingBits(&padded.data[padded_passstart[i]], &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
error = filter(&(*out)[filter_passstart[i]], &padded.data[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
}
ucvector_cleanup(&padded);
}
else
{
error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
}
}
break;
}
free(adam7);
}
return error;
}
static unsigned char readBitFromReversedStream ( size_t *  bitpointer,
const unsigned char *  bitstream 
)
static

Definition at line 1808 of file lodepng.cpp.

Referenced by Adam7_interlace(), addPaddingBits(), and readBitsFromReversedStream().

{
unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
(*bitpointer)++;
return result;
}
static unsigned readBitsFromReversedStream ( size_t *  bitpointer,
const unsigned char *  bitstream,
size_t  nbits 
)
static

Definition at line 1815 of file lodepng.cpp.

References readBitFromReversedStream().

Referenced by LodePNG_convert().

{
unsigned result = 0;
size_t i;
for(i = nbits - 1; i < nbits; i--) result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i;
return result;
}
static size_t searchCodeIndex ( const unsigned *  array,
size_t  array_size,
size_t  value 
)
static

Definition at line 1000 of file lodepng.cpp.

Referenced by addLengthDistance().

{
/*linear search implementation*/
/*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1;
return array_size - 1;*/
/*binary search implementation (not that much faster) (precondition: array_size > 0)*/
size_t left = 1;
size_t right = array_size - 1;
while(left <= right)
{
size_t mid = (left + right) / 2;
if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/
else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/
else return mid - 1;
}
return array_size - 1;
}
static void setBitOfReversedStream ( size_t *  bitpointer,
unsigned char *  bitstream,
unsigned char  bit 
)
static

Definition at line 1832 of file lodepng.cpp.

Referenced by Adam7_interlace(), and addPaddingBits().

{
/*the current bit in bitstream may be 0 or 1 for this to work*/
if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7)));
(*bitpointer)++;
}
static void ucvector_cleanup ( void *  p)
static

Definition at line 206 of file lodepng.cpp.

Referenced by addChunk_IDAT(), addChunk_IHDR(), addChunk_PLTE(), addChunk_tRNS(), filter(), LodeZlib_compress(), and preProcessScanlines().

{
((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
free(((ucvector*)p)->data);
((ucvector*)p)->data = NULL;
}
static void ucvector_init ( ucvector p)
static
static void ucvector_init_buffer ( ucvector p,
unsigned char *  buffer,
size_t  size 
)
static

Definition at line 251 of file lodepng.cpp.

References ucvector::allocsize, ucvector::data, and ucvector::size.

Referenced by LodeZlib_compress().

{
p->data = buffer;
p->allocsize = p->size = size;
}
static unsigned ucvector_push_back ( ucvector p,
unsigned char  c 
)
static
static unsigned ucvector_resize ( ucvector p,
size_t  size 
)
static

Definition at line 213 of file lodepng.cpp.

References ucvector::allocsize, ucvector::data, and ucvector::size.

Referenced by filter(), LodePNG_add32bitInt(), preProcessScanlines(), and ucvector_push_back().

{
if(size * sizeof(unsigned) > p->allocsize)
{
size_t newsize = size * sizeof(unsigned) * 2;
void* data = realloc(p->data, newsize);
if(data)
{
p->allocsize = newsize;
p->data = (unsigned char*)data;
p->size = size;
}
else return 0; /*error: not enough memory*/
}
else p->size = size;
return 1;
}
static void uivector_cleanup ( void *  p)
static

Definition at line 131 of file lodepng.cpp.

Referenced by Coin_cleanup(), deflateDynamic(), deflateFixed(), generateDistanceTree(), generateFixedTree(), HuffmanTree_cleanup(), and HuffmanTree_makeFromLengths2().

{
((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
free(((uivector*)p)->data);
((uivector*)p)->data = NULL;
}
static unsigned uivector_copy ( uivector p,
const uivector q 
)
static

Definition at line 178 of file lodepng.cpp.

References uivector::data, uivector::size, and uivector_resize().

Referenced by Coin_copy().

{
size_t i;
if(!uivector_resize(p, q->size)) return 0;
for(i = 0; i < q->size; i++) p->data[i] = q->data[i];
return 1;
}
static void uivector_init ( uivector p)
static
static unsigned uivector_push_back ( uivector p,
unsigned  c 
)
static

Definition at line 171 of file lodepng.cpp.

References uivector::data, uivector::size, and uivector_resize().

Referenced by addCoins(), addLengthDistance(), deflateDynamic(), encodeLZ77_brute(), and HuffmanTree_fillInCoins().

{
if(!uivector_resize(p, p->size + 1)) return 0;
p->data[p->size - 1] = c;
return 1;
}
static unsigned uivector_resize ( uivector p,
size_t  size 
)
static

Definition at line 138 of file lodepng.cpp.

References uivector::allocsize, uivector::data, and uivector::size.

Referenced by deflateDynamic(), generateDistanceTree(), generateFixedTree(), HuffmanTree_make2DTree(), HuffmanTree_makeFromFrequencies(), HuffmanTree_makeFromLengths(), HuffmanTree_makeFromLengths2(), uivector_copy(), uivector_push_back(), and uivector_resizev().

{
if(size * sizeof(unsigned) > p->allocsize)
{
size_t newsize = size * sizeof(unsigned) * 2;
void* data = realloc(p->data, newsize);
if(data)
{
p->allocsize = newsize;
p->data = (unsigned*)data;
p->size = size;
}
else return 0;
}
else p->size = size;
return 1;
}
static unsigned uivector_resizev ( uivector p,
size_t  size,
unsigned  value 
)
static

Definition at line 156 of file lodepng.cpp.

References uivector::data, uivector::size, and uivector_resize().

Referenced by deflateDynamic(), HuffmanTree_makeFromFrequencies(), and HuffmanTree_makeFromLengths2().

{
size_t oldsize = p->size, i;
if(!uivector_resize(p, size)) return 0;
for(i = oldsize; i < size; i++) p->data[i] = value;
return 1;
}
static void uivector_swap ( uivector p,
uivector q 
)
static

Definition at line 186 of file lodepng.cpp.

References uivector::allocsize, uivector::data, uivector::size, and languages::tmp.

Referenced by Coin_sort().

{
size_t tmp;
unsigned* tmpp;
tmp = p->size; p->size = q->size; q->size = tmp;
tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
tmpp = p->data; p->data = q->data; q->data = tmpp;
}
static unsigned update_adler32 ( unsigned  adler,
const unsigned char *  data,
unsigned  len 
)
static

Definition at line 1558 of file lodepng.cpp.

Referenced by adler32().

{
unsigned s1 = adler & 0xffff;
unsigned s2 = (adler >> 16) & 0xffff;
while(len > 0)
{
/*at least 5550 sums can be done before the sums overflow, saving us from a lot of module divisions*/
unsigned amount = len > 5550 ? 5550 : len;
len -= amount;
while(amount > 0)
{
s1 = (s1 + *data++);
s2 = (s2 + s1);
amount--;
}
s1 %= 65521;
s2 %= 65521;
}
return (s2 << 16) | s1;
}
static void vector_cleanup ( void *  p)
static

Definition at line 85 of file lodepng.cpp.

Referenced by HuffmanTree_fillInCoins(), and vector_cleanupd().

{
((vector*)p)->size = ((vector*)p)->allocsize = 0;
free(((vector*)p)->data);
((vector*)p)->data = NULL;
}
static void vector_cleanupd ( vector p,
void   dtorvoid * 
)
static

Definition at line 92 of file lodepng.cpp.

References vector_cleanup(), and vector_resized().

Referenced by HuffmanTree_makeFromFrequencies().

{
vector_resized(p, 0, dtor);
}
static void* vector_get ( vector p,
size_t  index 
)
static

Definition at line 114 of file lodepng.cpp.

References vector::data, and vector::typesize.

Referenced by HuffmanTree_fillInCoins(), and HuffmanTree_makeFromFrequencies().

{
return &((char*)p->data)[index * p->typesize];
}
static void vector_init ( vector p,
unsigned  typesize 
)
static

Definition at line 98 of file lodepng.cpp.

References vector::allocsize, vector::data, vector::size, and vector::typesize.

Referenced by HuffmanTree_makeFromFrequencies().

{
p->data = NULL;
p->size = p->allocsize = 0;
p->typesize = typesize;
}
static unsigned vector_resize ( vector p,
size_t  size 
)
static

Definition at line 60 of file lodepng.cpp.

References vector::allocsize, vector::data, vector::size, and vector::typesize.

Referenced by HuffmanTree_fillInCoins(), HuffmanTree_makeFromFrequencies(), and vector_resized().

{
if(size * p->typesize > p->allocsize)
{
size_t newsize = size * p->typesize * 2;
void* data = realloc(p->data, newsize);
if(data)
{
p->allocsize = newsize;
p->data = data;
p->size = size;
}
else return 0;
}
else p->size = size;
return 1;
}
static unsigned vector_resized ( vector p,
size_t  size,
void   dtorvoid * 
)
static

Definition at line 78 of file lodepng.cpp.

References vector::data, vector::size, vector::typesize, and vector_resize().

Referenced by HuffmanTree_makeFromFrequencies(), and vector_cleanupd().

{
size_t i;
if(size < p->size) for(i = size; i < p->size; i++) dtor(&((char*)(p->data))[i * p->typesize]);
return vector_resize(p, size);
}
static void vector_swap ( vector p,
vector q 
)
static

Definition at line 105 of file lodepng.cpp.

References vector::allocsize, vector::data, vector::size, and languages::tmp.

Referenced by HuffmanTree_makeFromFrequencies().

{
size_t tmp;
void* tmpp;
tmp = p->size; p->size = q->size; q->size = tmp;
tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
tmpp = p->data; p->data = q->data; q->data = tmpp;
}
static void writeLZ77data ( size_t *  bp,
ucvector out,
const uivector lz77_encoded,
const HuffmanTree codes,
const HuffmanTree codesD 
)
static

Definition at line 1301 of file lodepng.cpp.

References addBitsToStream(), addHuffmanSymbol(), uivector::data, DISTANCEEXTRA, FIRST_LENGTH_CODE_INDEX, HuffmanTree_getCode(), HuffmanTree_getLength(), LENGTHEXTRA, and uivector::size.

Referenced by deflateDynamic(), and deflateFixed().

{
size_t i = 0;
for(i = 0; i < lz77_encoded->size; i++)
{
unsigned val = lz77_encoded->data[i];
addHuffmanSymbol(bp, out, HuffmanTree_getCode(codes, val), HuffmanTree_getLength(codes, val));
if(val > 256) /*for a length code, 3 more things have to be added*/
{
unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
unsigned length_extra_bits = lz77_encoded->data[++i];
unsigned distance_code = lz77_encoded->data[++i];
unsigned distance_index = distance_code;
unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
unsigned distance_extra_bits = lz77_encoded->data[++i];
addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits);
addHuffmanSymbol(bp, out, HuffmanTree_getCode(codesD, distance_code), HuffmanTree_getLength(codesD, distance_code));
addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits);
}
}
}
static void writeSignature ( ucvector out)
static

Definition at line 3285 of file lodepng.cpp.

References ucvector_push_back().

Referenced by LodePNG_encode().

{
/*8 bytes PNG signature*/
ucvector_push_back(out, 137);
}

Variable Documentation

const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }
static

Definition at line 2567 of file lodepng.cpp.

const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }
static

Definition at line 2568 of file lodepng.cpp.

const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }
static

Definition at line 2565 of file lodepng.cpp.

const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }
static

Definition at line 2566 of file lodepng.cpp.

const unsigned CLCL[NUM_CODE_LENGTH_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
static

Definition at line 362 of file lodepng.cpp.

Referenced by deflateDynamic().

unsigned Crc32_crc_table[256]
static

Definition at line 1763 of file lodepng.cpp.

unsigned Crc32_crc_table_computed = 0
static

Definition at line 1762 of file lodepng.cpp.

const unsigned DISTANCEBASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}
static

Definition at line 358 of file lodepng.cpp.

Referenced by addLengthDistance().

const unsigned DISTANCEEXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}
static

Definition at line 360 of file lodepng.cpp.

Referenced by writeLZ77data().

const unsigned LENGTHBASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}
static

Definition at line 354 of file lodepng.cpp.

Referenced by addLengthDistance().

const unsigned LENGTHEXTRA[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}
static

Definition at line 356 of file lodepng.cpp.

Referenced by writeLZ77data().

const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings = {2, 1, 2048}

Definition at line 1704 of file lodepng.cpp.

Referenced by filter().

const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258
static

Definition at line 991 of file lodepng.cpp.