Compress-Zopfli
view release on metacpan or search on metacpan
zopflib/src/zopflipng/lodepng/lodepng.cpp view on Meta::CPAN
933934935936937938939940941942943944945946947948949950951952953954
unsigned treepos = 0, ct;
for
(;;)
{
if
(
*bp
>= inbitlength)
return
(unsigned)(-1); /
*error
: end of input memory reached without endcode*/
/*
decode the symbol from the tree. The
"readBitFromStream"
code is inlined in
the expression below because this is the biggest bottleneck
while
decoding
*/
ct = codetree->tree2d[(treepos << 1) + READBIT(
*bp
, in)];
++(
*bp
);
if
(ct < codetree->numcodes)
return
ct; /
*the
symbol is decoded,
return
it*/
else
treepos = ct - codetree->numcodes; /
*symbol
not yet decoded, instead move tree position*/
if
(treepos >= codetree->numcodes)
return
(unsigned)(-1); /
*error
: it appeared outside the codetree*/
}
}
#endif /*LODEPNG_COMPILE_DECODER*/
#ifdef LODEPNG_COMPILE_DECODER
/* ////////////////////////////////////////////////////////////////////////// */
/* / Inflator (Decompressor) / */
zopflib/src/zopflipng/lodepng/lodepng.cpp view on Meta::CPAN
43254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395/
*compressed
text chunk (zTXt)*/
static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
const unsigned char* data, size_t chunkLength)
{
unsigned error = 0;
unsigned i;
unsigned
length
, string2_begin;
char
*key
= 0;
ucvector decoded;
ucvector_init(
&decoded
);
while
(!error) /
*not
really a
while
loop, only used to break on error*/
{
for
(
length
= 0;
length
< chunkLength && data[
length
] != 0; ++
length
) ;
if
(
length
+ 2 >= chunkLength) CERROR_BREAK(error, 75); /
*no
null termination, corrupt?*/
if
(
length
< 1 ||
length
> 79) CERROR_BREAK(error, 89); /
*keyword
too short or long*/
key = (char*)lodepng_malloc(
length
+ 1);
if
(!key) CERROR_BREAK(error, 83); /
*alloc
fail*/
key[
length
] = 0;
for
(i = 0; i !=
length
; ++i) key[i] = (char)data[i];
if
(data[
length
+ 1] != 0) CERROR_BREAK(error, 72); /
*the
0 byte indicating compression must be 0*/
string2_begin =
length
+ 2;
if
(string2_begin > chunkLength) CERROR_BREAK(error, 75); /
*no
null termination, corrupt?*/
length
= chunkLength - string2_begin;
/
*will
fail
if
zlib error, e.g.
if
length
is too small*/
error = zlib_decompress(
&decoded
.data,
&decoded
.size,
(unsigned char*)(
&data
[string2_begin]),
length
, zlibsettings);
if
(error) break;
ucvector_push_back(
&decoded
, 0);
error = lodepng_add_text(info, key, (char*)decoded.data);
break;
}
lodepng_free(key);
ucvector_cleanup(
&decoded
);
return
error;
}
/
*international
text chunk (iTXt)*/
static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
const unsigned char* data, size_t chunkLength)
{
unsigned error = 0;
unsigned i;
unsigned
length
, begin, compressed;
char
*key
= 0,
*langtag
= 0,
*transkey
= 0;
ucvector decoded;
ucvector_init(
&decoded
);
while
(!error) /
*not
really a
while
loop, only used to break on error*/
{
/
*Quick
check
if
the chunk
length
isn't too small. Even without check
it
'd still fail with other error checks below if it'
s too short. This just gives a different error code.*/
if
(chunkLength < 5) CERROR_BREAK(error, 30); /
*iTXt
chunk too short*/
/
*read
the key*/
for
(
length
= 0;
length
< chunkLength && data[
length
] != 0; ++
length
) ;
if
(
length
+ 3 >= chunkLength) CERROR_BREAK(error, 75); /
*no
null termination char, corrupt?*/
zopflib/src/zopflipng/lodepng/lodepng.cpp view on Meta::CPAN
44314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474
for
(i = 0; i !=
length
; ++i) transkey[i] = (char)data[begin + i];
/
*read
the actual text*/
begin +=
length
+ 1;
length
= chunkLength < begin ? 0 : chunkLength - begin;
if
(compressed)
{
/
*will
fail
if
zlib error, e.g.
if
length
is too small*/
error = zlib_decompress(
&decoded
.data,
&decoded
.size,
(unsigned char*)(
&data
[begin]),
length
, zlibsettings);
if
(error) break;
if
(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size;
ucvector_push_back(
&decoded
, 0);
}
else
{
if
(!ucvector_resize(
&decoded
,
length
+ 1)) CERROR_BREAK(error, 83 /
*alloc
fail*/);
decoded.data[
length
] = 0;
for
(i = 0; i !=
length
; ++i) decoded.data[i] = data[begin + i];
}
error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data);
break;
}
lodepng_free(key);
lodepng_free(langtag);
lodepng_free(transkey);
ucvector_cleanup(
&decoded
);
return
error;
}
static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
{
if
(chunkLength != 7)
return
73; /
*invalid
tIME chunk size*/
info->time_defined = 1;
info->
time
.year = 256u * data[0] + data[1];
zopflib/src/zopflipng/lodepng/lodepng.h view on Meta::CPAN
1562156315641565156615671568156915701571157215731574157515761577157815791580158115821583A quick reference of some settings to set on the LodePNGState
For decoding:
state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums
state.decoder.ignore_crc: ignore CRC checksums
state.decoder.color_convert: convert internal PNG color to chosen one
state.decoder.read_text_chunks: whether to
read
in text metadata chunks
state.decoder.remember_unknown_chunks: whether to
read
in unknown chunks
state.info_raw.colortype: desired color type
for
decoded image
state.info_raw.bitdepth: desired bit depth
for
decoded image
state.info_raw....: more color settings, see struct LodePNGColorMode
state.info_png....:
no
settings
for
decoder but ouput, see struct LodePNGInfo
For encoding:
state.encoder.zlibsettings.btype: disable compression by setting it to 0
state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize
state.encoder.zlibsettings.minmatch: tweak min LZ77
length
to match
state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching
zopflib/src/zopflipng/lodepng/lodepng_util.cpp view on Meta::CPAN
3334353637383940414243444546474849505152{
unsigned w, h;
lodepng::State state;
lodepng_inspect(
&w
,
&h
,
&state
,
&png
[0], png.size());
return
state.info_png;
}
unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
const std::vector<unsigned char>& png)
{
// Listing chunks is based on the original file, not the decoded png info.
const unsigned char
*chunk
,
*begin
,
*end
,
*next
;
end =
&png
.back() + 1;
begin = chunk =
&png
.front() + 8;
while
(chunk + 8 < end && chunk >= begin)
{
char type[5];
lodepng_chunk_type(type, chunk);
if
(std::string(type).size() != 4)
return
1;
zopflib/src/zopflipng/lodepng/lodepng_util.cpp view on Meta::CPAN
354355356357358359360361362363364365366367368369370371372373374375376377378379380
{
//addresses are encoded as
values
> numcodes
tree2d[2 * treepos + bit] = ++nodefilled + numcodes;
treepos = nodefilled;
}
}
else
treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
}
return
0;
}
int
decode(bool& decoded, unsigned long& result, size_t& treepos, unsigned long bit) const
{ //Decodes a symbol from the tree
unsigned long numcodes = (unsigned long)tree2d.size() / 2;
if
(treepos >= numcodes)
return
11; //error: you appeared outside the codetree
result = tree2d[2 * treepos + bit];
decoded = (result < numcodes);
treepos = decoded ? 0 : result - numcodes;
return
0;
}
//2D representation of a huffman tree: one dimension is
"0"
or
"1"
, the other contains all nodes and leaves.
std::vector<unsigned long> tree2d;
};
void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, size_t inpos = 0)
{
size_t bp = 0,
pos
= 0; //bit pointer and byte pointer
error = 0;
zopflib/src/zopflipng/lodepng/lodepng_util.cpp view on Meta::CPAN
404405406407408409410411412413414415416417418419420421422423424425426427428429430
for
(size_t i = 256; i <= 279; i++) bitlen[i] = 7;
tree.makeFromLengths(bitlen, 15);
treeD.makeFromLengths(bitlenD, 15);
}
//the code tree
for
Huffman codes, dist codes, and code
length
codes
HuffmanTree codetree, codetreeD, codelengthcodetree;
unsigned long huffmanDecodeSymbol(const unsigned char* in, size_t& bp, const HuffmanTree& tree, size_t inlength)
{
//decode a single symbol from
given
list of bits
with
given
code tree.
return
value is the symbol
bool decoded; unsigned long ct;
for
(size_t treepos = 0;;)
{
if
((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10;
return
0; } //error: end reached without endcode
error = tree.decode(decoded, ct, treepos, readBitFromStream(bp, in));
if
(error)
return
0; //stop, an error happened
if
(decoded)
return
ct;
}
}
void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD,
const unsigned char* in, size_t& bp, size_t inlength)
{
size_t bpstart = bp;
//get the tree of a deflated block
with
dynamic tree, the tree itself is also Huffman compressed
with
a known tree
std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
if
(bp >> 3 >= inlength - 2) { error = 49;
return
; } //the bit pointer is or will go past the memory
( run in 0.292 second using v1.01-cache-2.11-cpan-bf8d7bb2d05 )