Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:48

0001 
0002 // G.Barrand: pure header version of fpng found at https://github.com/richgel999/fpng
0003 
0004 // fpng.cpp 1.0.6 - Fast 24/32bpp .PNG image writer/reader. See unlicense at the end of this file.
0005 // PNG's generated by this code have been tested to load successfully with stb_image.h, lodepng.cpp, wuffs, libpng, and pngcheck.
0006 //
0007 // Uses code from the simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299
0008 // Some low-level Deflate/Huffman functions derived from the original 2011 Google Code version of miniz (public domain by R. Geldreich, Jr.): https://code.google.com/archive/p/miniz/
0009 // Low-level Huffman code size function: public domain, originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
0010 //
0011 
0012 #include <assert.h>
0013 #include <string.h>
0014 #include <stdio.h>
0015 
0016 namespace tools {
0017 namespace fpng
0018 {
0019     static const int FPNG_FALSE = 0;
0020     static const uint8_t FPNG_FDEC_VERSION = 0;
0021     static const uint32_t FPNG_MAX_SUPPORTED_DIM = 1 << 24;
0022 
0023     template <typename S> static inline S maximum(S a, S b) { return (a > b) ? a : b; }
0024     template <typename S> static inline S minimum(S a, S b) { return (a < b) ? a : b; }
0025 
0026     // A good compiler should be able to optimize these routines - hopefully. They are crucial for performance.
0027     static inline uint32_t READ_LE32(const void* p)
0028     {
0029         const uint8_t* pBytes = (const uint8_t*)p;
0030         return ((uint32_t)pBytes[0]) | (((uint32_t)pBytes[1]) << 8U) | (((uint32_t)pBytes[2]) << 16U) | (((uint32_t)pBytes[3]) << 24U);
0031     }
0032 
0033     static inline uint32_t READ_BE32(const void* p)
0034     {
0035         const uint8_t* pBytes = (const uint8_t*)p;
0036         return ((uint32_t)pBytes[3]) | (((uint32_t)pBytes[2]) << 8U) | (((uint32_t)pBytes[1]) << 16U) | (((uint32_t)pBytes[0]) << 24U);
0037     }
0038 
0039     static inline void WRITE_LE32(const void* p, uint32_t v)
0040     {
0041         uint8_t* pBytes = (uint8_t*)p;
0042         pBytes[0] = (uint8_t)(v);
0043         pBytes[1] = (uint8_t)(v >> 8);
0044         pBytes[2] = (uint8_t)(v >> 16);
0045         pBytes[3] = (uint8_t)(v >> 24);
0046     }
0047 
0048     static inline void WRITE_LE64(const void* p, uint64_t v)
0049     {
0050         uint8_t* pBytes = (uint8_t*)p;
0051         pBytes[0] = (uint8_t)(v);
0052         pBytes[1] = (uint8_t)(v >> 8);
0053         pBytes[2] = (uint8_t)(v >> 16);
0054         pBytes[3] = (uint8_t)(v >> 24);
0055         pBytes[4] = (uint8_t)(v >> 32);
0056         pBytes[5] = (uint8_t)(v >> 40);
0057         pBytes[6] = (uint8_t)(v >> 48);
0058         pBytes[7] = (uint8_t)(v >> 56);
0059     }
0060 
0061     // Customized the very common case of reading a 24bpp pixel from memory
0062     static inline uint32_t READ_RGB_PIXEL(const void* p)
0063     {
0064         const uint8_t* pBytes = (const uint8_t*)p;
0065         return ((uint32_t)pBytes[0]) | (((uint32_t)pBytes[1]) << 8U) | (((uint32_t)pBytes[2]) << 16U);
0066     }
0067 
0068     // See "Slicing by 4" CRC-32 algorithm here: 
0069     // https://create.stephan-brumme.com/crc32/
0070 
0071     // Precomputed 4KB of CRC-32 tables
0072     static const uint32_t g_crc32_4[4][256] = {
0073     {00, 016701630226, 035603460454, 023102250672, 0733342031, 016032572217, 035130722465, 023631112643, 01666704062, 017167134244, 034065364436, 022764554610, 01155446053, 017654276275, 034756026407, 022057616621, 03555610144, 015254020362, 036356270510, 020457440736, 03266552175, 015567362353, 036465132521, 020364702707, 02333114126, 014432724300, 037530574572, 021231344754, 02400256117, 014301466331, 037203636543, 021502006765,
0074     07333420310, 011432210136, 032530040744, 024231670562, 07400762321, 011301152107, 032203302775, 024502532553, 06555324372, 010254514154, 033356744726, 025457174500, 06266066343, 010567656165, 033465406717, 025364236531, 04666230254, 012167400072, 031065650600, 027764060426, 04155172265, 012654742043, 031756512631, 027057322417, 05000534236, 013701304010, 030603154662, 026102764444, 05733676207, 013032046021, 030130216653, 026631426475,
0075     016667040620, 0166670406, 023064420274, 035765210052, 016154302611, 0655532437, 023757762245, 035056152063, 017001744642, 01700174464, 022602324216, 034103514030, 017732406673, 01033236455, 022131066227, 034630656001, 015332650764, 03433060542, 020531230330, 036230400116, 015401512755, 03300322573, 020202172301, 036503742127, 014554154706, 02255764520, 021357534352, 037456304174, 014267216737, 02566426511, 021464676363, 037365046145,
0076     011554460530, 07255250716, 024357000164, 032456630342, 011267722501, 07566112727, 024464342155, 032365572373, 010332364552, 06433554774, 025531704106, 033230134320, 010401026563, 06300616745, 025202446137, 033503276311, 012001270474, 04700440652, 027602610020, 031103020206, 012732132445, 04033702663, 027131552011, 031630362237, 013667574416, 05166344630, 026064114042, 030765724264, 013154636427, 05655006601, 026757256073, 030056466255,
0077     035556101440, 023257731666, 0355561014, 016454351232, 035265243471, 023564473657, 0466623025, 016367013203, 034330605422, 022431035604, 01533265076, 017232455250, 034403547413, 022302377635, 01200127047, 017501717261, 036003711504, 020702121722, 03600371150, 015101541376, 036730453535, 020031263713, 03133033161, 015632603347, 037665015566, 021164625740, 02066475132, 014767245314, 037156357557, 021657567771, 02755737103, 014054107325,
0078     032665521750, 024164311576, 07066141304, 011767771122, 032156663761, 024657053547, 07755203335, 011054433113, 033003225732, 025702415514, 06600645366, 010101075140, 033730167703, 025031757525, 06133507357, 010632337171, 031330331614, 027431501432, 04533751240, 012232161066, 031403073625, 027302643403, 04200413271, 012501223057, 030556435676, 026257205450, 05355055222, 013454665004, 030265777647, 026564147461, 05466317213, 013367527035,
0079     023331141260, 035430771046, 016532521634, 0233311412, 023402203251, 035303433077, 016201663605, 0500053423, 022557645202, 034256075024, 017354225656, 01455415470, 022264507233, 034565337015, 017467167667, 01366757441, 020664751324, 036165161102, 015067331770, 03766501556, 020157413315, 036656223133, 015754073741, 03055643567, 021002055346, 037703665160, 014601435712, 02100205534, 021731317377, 037030527151, 014132777723, 02633147505,
0080     024002561170, 032703351356, 011601101524, 07100731702, 024731623141, 032030013367, 011132243515, 07633473733, 025664265112, 033165455334, 010067605546, 06766035760, 025157127123, 033656717305, 010754547577, 06055377751, 027557371034, 031256541212, 012354711460, 04455121646, 027264033005, 031565603223, 012467453451, 04366263677, 026331475056, 030430245270, 013532015402, 05233625624, 026402737067, 030303107241, 013201357433, 05500567615,
0081     }, { 00,03106630501,06215461202,05313251703,014433142404,017535772105,012626523606,011720313307,031066305010,032160535511,037273764212,034375154713,025455247414,026553477115,023640626616,020746016317,011260411121,012366221420,017075070323,014173640622,05653553525,06755363024,03446132727,0540702226,020206714131,023300124430,026013375333,025115545632,034635656535,037733066034,032420237737,031526407236,
0082     022541022242,021447612743,024754443040,027652273541,036172160646,035074750347,030367501444,033261331145,013527327252,010421517753,015732746050,016634176551,07114265656,04012455357,01301604454,02207034155,033721433363,030627203662,035534052161,036432662460,027312571767,024214341266,021107110565,022001720064,02747736373,01641106672,04552357171,07454567470,016374674777,015272044276,010161215575,013067425074,
0083     036036247405,035130477104,030223626607,033325016306,022405305001,021503535500,024610764203,027716154702,07050142415,04156772114,01245523617,02343313316,013463000011,010565630510,015676461213,016770251712,027256656524,024350066025,021043237726,022145407227,033665714120,030763124421,035470375322,036576545623,016230553534,015336363035,010025132736,013123702237,02603411130,01705221431,04416070332,07510640633,
0084     014577265647,017471455346,012762604445,011664034144,0144327243,03042517742,06351746041,05257176540,025511160657,026417750356,023704501455,020602331154,031122022253,032024612752,037337443051,034231273550,05717674766,06611044267,03502215564,0404425065,011324736362,012222106663,017131357160,014037567461,034771571776,037677341277,032564110574,031462720075,020342433372,023244203673,026157052170,025051662471,
0085     07340714113,04246124412,01155375311,02053545610,013773656517,010675066016,015566237715,016460407214,036326411103,035220221402,030133070301,033035640600,022715553507,021613363006,024500132705,027406702204,016120305032,015026535533,010335764230,013233154731,02513247436,01415477137,04706626634,07600016335,027146000022,024040630523,021353461220,022255251721,033575142426,030473772127,035760523624,036666313325,
0086     025601736351,026707106650,023414357153,020512567452,031232674755,032334044254,037027215557,034121425056,014667433341,017761203640,012472052143,011574662442,0254571745,03352341244,06041110547,05147720046,034461327270,037567517771,032674746072,031772176573,020052265674,023154455375,026247604476,025341034177,05407022260,06501612761,03612443062,0714273563,011034160664,012132750365,017221501466,014327331167,
0087     031376553516,032270363017,037163132714,034065702215,025745411112,026643221413,023550070310,020456640611,0310656506,03216066007,06105237704,05003407205,014723714102,017625124403,012536375300,011430545601,020116142437,023010772136,026303523635,025205313334,034525000033,037423630532,032730461231,031636251730,011170247427,012076477126,017365626625,014263016324,05543305023,06445535522,03756764221,0650154720,
0088     013637571754,010731341255,015422110556,016524720057,07204433350,04302203651,01011052152,02117662453,022651674744,021757044245,024444215546,027542425047,036262736340,035364106641,030077357142,033171567443,02457160675,01551750374,04642501477,07744331176,016064022271,015162612770,010271443073,013377273572,033431265665,030537455364,035624604467,036722034166,027002327261,024104517760,021217746063,022311176562,
0089     }, { 00,0160465067,0341152156,0221537131,0702324334,0662741353,0443276262,0523613205,01604650670,01764235617,01545702726,01425367741,01106574544,01066111523,01247426412,01327043475,03411521560,03571144507,03750473436,03630016451,03313605654,03273260633,03052757702,03132332765,02215371310,02375714377,02154223246,02034646221,02517055024,02477430043,02656107172,02736562115,
0090     07023243340,07143626327,07362311216,07202774271,07721167074,07641502013,07460035122,07500450145,06627413530,06747076557,06566541466,06406124401,06125737604,06045352663,06264665752,06304200735,04432762620,04552307647,04773630776,04613255711,04330446514,04250023573,04071514442,04111171425,05236132050,05356557037,05177060106,05017405161,05534216364,05454673303,05675344232,05715721255,
0091     016046506700,016126163767,016307454656,016267031631,016744622434,016624247453,016405770562,016565315505,017642356170,017722733117,017503204026,017463661041,017140072244,017020417223,017201120312,017361545375,015457027260,015537442207,015716175336,015676510351,015355303154,015235766133,015014251002,015174634065,014253677410,014333212477,014112725546,014072340521,014551553724,014431136743,014610401672,014770064615,
0092     011065745440,011105320427,011324617516,011244272571,011767461774,011607004713,011426533622,011546156645,010661115230,010701570257,010520047366,010440422301,010163231104,010003654163,010222363052,010342706035,012474264120,012514601147,012735336076,012655753011,012376140214,012216525273,012037012342,012157477325,013270434750,013310051737,013131566606,013051103661,013572710464,013412375403,013633642532,013753227555,
0093     034115215600,034075670667,034254347756,034334722731,034617131534,034777554553,034556063462,034436406405,035711445070,035671020017,035450517126,035530172141,035013761344,035173304323,035352633212,035232256275,037504734360,037464351307,037645666236,037725203251,037206410054,037366075033,037147542102,037027127165,036300164510,036260501577,036041036446,036121453421,036402240624,036562625643,036743312772,036623777715,
0094     033136056540,033056433527,033277104416,033317561471,033634372674,033754717613,033575220722,033415645745,032732606330,032652263357,032473754266,032513331201,032030522004,032150147063,032371470152,032211015135,030527577020,030447112047,030666425176,030706040111,030225653314,030345236373,030164701242,030004364225,031323327650,031243742637,031062275706,031102610761,031421003564,031541466503,031760151432,031600534455,
0095     022153713100,022033376167,022212641056,022372224031,022651437234,022731052253,022510565362,022470100305,023757143770,023637526717,023416011626,023576474641,023055267444,023135602423,023314335512,023274750575,021542232460,021422657407,021603360536,021763705551,021240116754,021320573733,021101044602,021061421665,020346462210,020226007277,020007530346,020167155321,020444746124,020524323143,020705614072,020665271015,
0096     025170550240,025010135227,025231402316,025351067371,025672674174,025712211113,025533726022,025453343045,024774300430,024614765457,024435252566,024555637501,024076024704,024116441763,024337176652,024257513635,026561071720,026401414747,026620123676,026740546611,026263355414,026303730473,026122207542,026042662525,027365621150,027205244137,027024773006,027144316061,027467505264,027507160203,027726457332,027646032355,
0097     }, { 00,027057063545,025202344213,02255327756,021730513527,06767570062,04532657734,023565634271,030555024357,017502047612,015757360144,032700303401,011265537670,036232554335,034067673463,013030610126,012006253637,035051230372,037204117424,010253174161,033736740310,014761723655,016534404103,031563467446,022553277560,05504214025,07751133773,020706150236,03263764047,024234707502,026061420254,01036443711,
0098     024014527476,03043544133,01216663665,026241600320,05724034151,022773057414,020526370342,07571313607,014541503721,033516560264,031743647532,016714624077,035271010206,012226073743,010073354015,037024337550,036012774241,011045717704,013210430052,034247453517,017722267766,030775204223,032520123575,015577140030,06547750116,021510733453,023745414305,04712477640,027277243431,0220220174,02075107622,025022164367,
0099     023305054075,04352037530,06107310266,021150373723,02435547552,025462524017,027637603741,0660660204,013650070322,034607013667,036452334131,011405357474,032160563605,015137500340,017362627416,030335644153,031303207642,016354264307,014101143451,033156120114,010433714365,037464777620,035631450176,012666433433,01656223515,026601240050,024454167706,03403104243,020166730032,07131753577,05364474221,022333417764,
0100     07311573403,020346510146,022113637610,05144654355,026421060124,01476003461,03623324337,024674347672,037644557754,010613534211,012446613547,035411670002,016174044273,031123027736,033376300060,014321363525,015317720234,032340743771,030115464027,017142407562,034427233713,013470250256,011625177500,036672114045,025642704163,02615767426,0440440370,027417423635,04172217444,023125274101,021370153657,06327130312,
0101     035526333073,012571350536,010724077260,037773014725,014216620554,033241643011,031014564747,016043507202,05073317324,022024374661,020271053137,07226030472,024743604603,03714667346,01541540410,026516523155,027520160644,0577103301,02722224457,025775247112,06210473363,021247410626,023012737170,04045754435,017075144513,030022127056,032277200700,015220263245,036745457034,011712434571,013547713227,034510770762,
0102     011532614405,036565677140,034730550616,013767533353,030202307122,017255364467,015000043331,032057020674,021067630752,06030653217,04265574541,023232517004,0757323275,027700340730,025555067066,02502004523,03534447232,024563424777,026736703021,01761760564,022204154715,05253137250,07006210506,020051273043,033061463165,014036400420,016263727376,031234744633,012751170442,035706113107,037553234651,010504257314,
0103     016623367006,031674304543,033421023215,014476040750,037113674521,010144617064,012311530732,035346553277,026376343351,01321320614,03174007142,024123064407,07446650676,020411633333,022644514465,05613577120,04625134631,023672157374,021427270422,06470213167,025115427316,02142444653,0317763105,027340700440,034370110566,013327173023,011172254775,036125237230,015440403041,032417460504,030642747252,017615724717,
0104     032637640470,015660623135,017435504663,030462567326,013107353157,034150330412,036305017344,011352074601,02362664727,025335607262,027160520534,0137543071,023452377200,04405314745,06650033013,021607050556,020631413247,07666470702,05433757054,022464734511,01101100760,026156163225,024303244573,03354227036,010364437110,037333454455,035166773303,012131710646,031454124437,016403147172,014656260624,033601203361,
0105     } };
0106 
0107     static uint32_t crc32_slice_by_4(const void* pData, size_t data_len, uint32_t cur_crc32 = 0)
0108     {
0109         uint32_t crc = ~cur_crc32;
0110         const uint32_t* pData32 = static_cast<const uint32_t*>(pData);
0111 
0112         for (; data_len >= sizeof(uint32_t); ++pData32, data_len -= 4)
0113         {
0114             uint32_t v = READ_LE32(pData32) ^ crc;
0115             crc = g_crc32_4[0][v >> 24] ^ g_crc32_4[1][(v >> 16) & 0xFF] ^ g_crc32_4[2][(v >> 8) & 0xFF] ^ g_crc32_4[3][v & 0xFF];
0116         }
0117 
0118         for (const uint8_t* pData8 = reinterpret_cast<const uint8_t*>(pData32); data_len; --data_len)
0119             crc = (crc >> 8) ^ g_crc32_4[0][(crc & 0xFF) ^ *pData8++];
0120 
0121         return ~crc;
0122     }
0123 
0124     inline uint32_t fpng_crc32(const void* pData, size_t size, uint32_t prev_crc32)
0125     {
0126         return crc32_slice_by_4(pData, size, prev_crc32);
0127     }
0128 
0129     static uint32_t fpng_adler32_scalar(const uint8_t* ptr, size_t buf_len, uint32_t adler)
0130     {
0131         uint32_t i, s1 = (uint32_t)(adler & 0xffff), s2 = (uint32_t)(adler >> 16); uint32_t block_len = (uint32_t)(buf_len % 5552);
0132         if (!ptr) return FPNG_ADLER32_INIT;
0133         while (buf_len) {
0134             for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
0135                 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
0136                 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
0137             }
0138             for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
0139             s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
0140         }
0141         return (s2 << 16) + s1;
0142     }
0143 
0144     inline uint32_t fpng_adler32(const void* pData, size_t size, uint32_t adler)
0145     {
0146         return fpng_adler32_scalar((const uint8_t*)pData, size, adler);
0147     }
0148 
0149     // Ensure we've been configured for endianness correctly.
0150     static inline bool endian_check()
0151     {
0152         uint32_t endian_check = 0;
0153         WRITE_LE32(&endian_check, 0x1234ABCD);
0154         const uint32_t first_byte = reinterpret_cast<const uint8_t*>(&endian_check)[0];
0155         return first_byte == 0xCD;
0156     }
0157         
0158     static const uint16_t g_defl_len_sym[256] = {
0159       257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272,
0160       273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276,
0161       277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
0162       279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
0163       281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
0164       282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,
0165       283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,
0166       284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 };
0167 
0168     static const uint8_t g_defl_len_extra[256] = {
0169       0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
0170       4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
0171       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
0172       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 };
0173 
0174     static const uint8_t g_defl_small_dist_sym[512] = {
0175       0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
0176       11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
0177       13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
0178       14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
0179       14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
0180       15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,
0181       16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
0182       16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
0183       16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
0184       17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
0185       17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
0186       17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 };
0187         
0188     static const uint32_t g_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
0189 
0190     // Huffman tables generated by fpng_test -t @filelist.txt. Total alpha files : 1440, Total opaque files : 5627.
0191     // Feel free to retrain the encoder on your opaque/alpha PNG files by setting FPNG_TRAIN_HUFFMAN_TABLES and running fpng_test with the -t option.
0192     static const uint8_t g_dyn_huff_3[] = {
0193     120, 1, 237, 195, 3, 176, 110, 89, 122, 128, 225, 247, 251, 214, 218, 248, 113, 124, 173, 190, 109, 12, 50, 201, 196, 182, 109, 219, 182, 109, 219, 182,
0194     109, 219, 201, 36, 147, 153, 105, 235, 246, 53, 142, 207, 143, 141, 181, 214, 151, 93, 117, 170, 78, 117, 117, 58, 206, 77, 210, 217, 169, 122 };
0195     const uint32_t DYN_HUFF_3_BITBUF = 30, DYN_HUFF_3_BITBUF_SIZE = 7;
0196     static const struct { uint8_t m_code_size; uint16_t m_code; } g_dyn_huff_3_codes[288] = {
0197     {2,0},{4,2},{4,10},{5,14},{5,30},{6,25},{6,57},{6,5},{6,37},{7,3},{7,67},{7,35},{7,99},{8,11},{8,139},{8,75},{8,203},{8,43},{8,171},{8,107},{9,135},{9,391},{9,71},{9,327},{9,199},{9,455},{9,39},{9,295},{9,167},{9,423},{9,103},{10,183},
0198     {9,359},{10,695},{10,439},{10,951},{10,119},{10,631},{10,375},{10,887},{10,247},{10,759},{10,503},{11,975},{11,1999},{11,47},{11,1071},{12,1199},{11,559},{12,3247},{12,687},{11,1583},{12,2735},{12,1711},{12,3759},{12,431},{12,2479},{12,1455},{12,3503},{12,943},{12,2991},{12,1967},{12,4015},{12,111},
0199     {12,2159},{12,1135},{12,3183},{12,623},{12,2671},{12,1647},{12,3695},{12,367},{12,2415},{12,1391},{12,3439},{12,879},{12,2927},{12,1903},{12,3951},{12,239},{12,2287},{12,1263},{12,3311},{12,751},{12,2799},{12,1775},{12,3823},{12,495},{12,2543},{12,1519},{12,3567},{12,1007},{12,3055},{12,2031},{12,4079},{12,31},
0200     {12,2079},{12,1055},{12,3103},{12,543},{12,2591},{12,1567},{12,3615},{12,287},{12,2335},{12,1311},{12,3359},{12,799},{12,2847},{12,1823},{12,3871},{12,159},{12,2207},{12,1183},{12,3231},{12,671},{12,2719},{12,1695},{12,3743},{12,415},{12,2463},{12,1439},{12,3487},{12,927},{12,2975},{12,1951},{12,3999},{12,95},
0201     {12,2143},{12,1119},{12,3167},{12,607},{12,2655},{12,1631},{12,3679},{12,351},{12,2399},{12,1375},{12,3423},{12,863},{12,2911},{12,1887},{12,3935},{12,223},{12,2271},{12,1247},{12,3295},{12,735},{12,2783},{12,1759},{12,3807},{12,479},{12,2527},{12,1503},{12,3551},{12,991},{12,3039},{12,2015},{12,4063},{12,63},
0202     {12,2111},{12,1087},{12,3135},{12,575},{12,2623},{12,1599},{12,3647},{12,319},{12,2367},{12,1343},{12,3391},{12,831},{12,2879},{12,1855},{12,3903},{12,191},{12,2239},{12,1215},{12,3263},{12,703},{12,2751},{12,1727},{12,3775},{12,447},{12,2495},{12,1471},{12,3519},{12,959},{12,3007},{12,1983},{12,4031},{12,127},
0203     {12,2175},{12,1151},{12,3199},{12,639},{12,2687},{12,1663},{12,3711},{12,383},{12,2431},{12,1407},{12,3455},{12,895},{12,2943},{11,303},{12,1919},{12,3967},{11,1327},{12,255},{11,815},{11,1839},{11,175},{10,1015},{10,15},{10,527},{10,271},{10,783},{10,143},{10,655},{10,399},{10,911},{10,79},{10,591},
0204     {9,231},{10,335},{9,487},{9,23},{9,279},{9,151},{9,407},{9,87},{9,343},{9,215},{9,471},{9,55},{8,235},{8,27},{8,155},{8,91},{8,219},{8,59},{8,187},{8,123},{7,19},{7,83},{7,51},{7,115},{6,21},{6,53},{6,13},{6,45},{5,1},{5,17},{5,9},{4,6},
0205     {12,2303},{6,29},{0,0},{0,0},{8,251},{0,0},{0,0},{8,7},{0,0},{10,847},{0,0},{10,207},{12,1279},{10,719},{12,3327},{12,767},{12,2815},{12,1791},{12,3839},{12,511},{12,2559},{12,1535},{9,311},{12,3583},{12,1023},{12,3071},{10,463},{12,2047},{6,61},{12,4095},{0,0},{0,0}
0206     };
0207 
0208     static const uint8_t g_dyn_huff_4[] = {
0209     120, 1, 229, 196, 99, 180, 37, 103, 218, 128, 225, 251, 121, 171, 106, 243, 216, 231, 180, 109, 196, 182, 51, 51, 73, 6, 201, 216, 182, 109, 219, 182,
0210     17, 140, 98, 219, 102, 219, 60, 125, 172, 205, 170, 122, 159, 111, 213, 143, 179, 214, 94, 189, 58, 153, 104, 166, 103, 190, 247, 199, 117 };
0211     const uint32_t DYN_HUFF_4_BITBUF = 1, DYN_HUFF_4_BITBUF_SIZE = 2;
0212     static const struct { uint8_t m_code_size; uint16_t m_code; } g_dyn_huff_4_codes[288] = {
0213     {2,0},{4,2},{5,6},{6,30},{6,62},{6,1},{7,41},{7,105},{7,25},{7,89},{7,57},{7,121},{8,117},{8,245},{8,13},{8,141},{8,77},{8,205},{8,45},{8,173},{8,109},{8,237},{8,29},{8,157},{8,93},{8,221},{8,61},{9,83},{9,339},{9,211},{9,467},{9,51},
0214     {9,307},{9,179},{9,435},{9,115},{9,371},{9,243},{9,499},{9,11},{9,267},{9,139},{9,395},{9,75},{9,331},{9,203},{9,459},{9,43},{9,299},{10,7},{10,519},{10,263},{10,775},{10,135},{10,647},{10,391},{10,903},{10,71},{10,583},{10,327},{10,839},{10,199},{10,711},{10,455},
0215     {10,967},{10,39},{10,551},{10,295},{10,807},{10,167},{10,679},{10,423},{10,935},{10,103},{10,615},{11,463},{11,1487},{11,975},{10,359},{10,871},{10,231},{11,1999},{11,47},{11,1071},{11,559},{10,743},{10,487},{11,1583},{11,303},{11,1327},{11,815},{11,1839},{11,175},{11,1199},{11,687},{11,1711},
0216     {11,431},{11,1455},{11,943},{11,1967},{11,111},{11,1135},{11,623},{11,1647},{11,367},{11,1391},{11,879},{11,1903},{11,239},{11,1263},{11,751},{11,1775},{11,495},{11,1519},{11,1007},{11,2031},{11,31},{11,1055},{11,543},{11,1567},{11,287},{11,1311},{11,799},{11,1823},{11,159},{11,1183},{11,671},{11,1695},
0217     {11,415},{11,1439},{11,927},{11,1951},{11,95},{11,1119},{11,607},{11,1631},{11,351},{11,1375},{11,863},{11,1887},{11,223},{11,1247},{11,735},{11,1759},{11,479},{11,1503},{11,991},{11,2015},{11,63},{11,1087},{11,575},{11,1599},{11,319},{11,1343},{11,831},{11,1855},{11,191},{11,1215},{11,703},{11,1727},
0218     {11,447},{11,1471},{11,959},{11,1983},{11,127},{11,1151},{11,639},{11,1663},{11,383},{10,999},{10,23},{10,535},{10,279},{11,1407},{11,895},{11,1919},{11,255},{11,1279},{10,791},{10,151},{10,663},{10,407},{10,919},{10,87},{10,599},{10,343},{10,855},{10,215},{10,727},{10,471},{10,983},{10,55},
0219     {10,567},{10,311},{10,823},{10,183},{10,695},{10,439},{10,951},{10,119},{10,631},{10,375},{10,887},{10,247},{10,759},{10,503},{10,1015},{10,15},{10,527},{10,271},{10,783},{10,143},{10,655},{10,399},{9,171},{9,427},{9,107},{9,363},{9,235},{9,491},{9,27},{9,283},{9,155},{9,411},
0220     {9,91},{9,347},{9,219},{9,475},{9,59},{9,315},{9,187},{9,443},{8,189},{9,123},{8,125},{8,253},{8,3},{8,131},{8,67},{8,195},{8,35},{8,163},{8,99},{8,227},{8,19},{7,5},{7,69},{7,37},{7,101},{7,21},{7,85},{6,33},{6,17},{6,49},{5,22},{4,10},
0221     {12,2047},{0,0},{6,9},{0,0},{0,0},{0,0},{8,147},{0,0},{0,0},{7,53},{0,0},{9,379},{0,0},{9,251},{10,911},{10,79},{11,767},{10,591},{10,335},{10,847},{10,207},{10,719},{11,1791},{11,511},{9,507},{11,1535},{11,1023},{12,4095},{5,14},{0,0},{0,0},{0,0}
0222     };
0223 
0224 #define TOOLS_FPNG_PUT_BITS(bb, ll) do { uint32_t b = bb, l = ll; assert(/*(l) >= 0 &&*/ (l) <= 16); assert((b) < (1ULL << (l))); bit_buf |= (((uint64_t)(b)) << bit_buf_size); bit_buf_size += (l); assert(bit_buf_size <= 64); } while(0)
0225 #define TOOLS_FPNG_PUT_BITS_CZ(bb, ll) do { uint32_t b = bb, l = ll; assert((l) >= 1 && (l) <= 16); assert((b) < (1ULL << (l))); bit_buf |= (((uint64_t)(b)) << bit_buf_size); bit_buf_size += (l); assert(bit_buf_size <= 64); } while(0)
0226 
0227 #define TOOLS_FPNG_PUT_BITS_FLUSH do { \
0228     if ((dst_ofs + 8) > dst_buf_size) \
0229         return 0; \
0230     WRITE_LE64(pDst + dst_ofs, bit_buf); \
0231     uint32_t bits_to_shift = bit_buf_size & ~7; \
0232     dst_ofs += (bits_to_shift >> 3); \
0233     assert(bits_to_shift < 64); \
0234     bit_buf = bit_buf >> bits_to_shift; \
0235     bit_buf_size -= bits_to_shift; \
0236 } while(0)
0237 
0238 #define TOOLS_FPNG_PUT_BITS_FORCE_FLUSH do { \
0239     while (bit_buf_size > 0) \
0240     { \
0241         if ((dst_ofs + 1) > dst_buf_size) \
0242             return 0; \
0243         *(uint8_t*)(pDst + dst_ofs) = (uint8_t)bit_buf; \
0244         dst_ofs++; \
0245         bit_buf >>= 8; \
0246         bit_buf_size -= 8; \
0247     } \
0248 } while(0)
0249 
0250     enum
0251     {
0252         DEFL_MAX_HUFF_TABLES = 3,
0253         DEFL_MAX_HUFF_SYMBOLS = 288,    
0254         DEFL_MAX_HUFF_SYMBOLS_0 = 288,  
0255         DEFL_MAX_HUFF_SYMBOLS_1 = 32,
0256         DEFL_MAX_HUFF_SYMBOLS_2 = 19,
0257         DEFL_LZ_DICT_SIZE = 32768,
0258         DEFL_LZ_DICT_SIZE_MASK = DEFL_LZ_DICT_SIZE - 1,
0259         DEFL_MIN_MATCH_LEN = 3,
0260         DEFL_MAX_MATCH_LEN = 258
0261     };
0262 
0263     struct defl_huff
0264     {
0265         uint16_t m_huff_count[DEFL_MAX_HUFF_TABLES][DEFL_MAX_HUFF_SYMBOLS];
0266         uint16_t m_huff_codes[DEFL_MAX_HUFF_TABLES][DEFL_MAX_HUFF_SYMBOLS];
0267         uint8_t m_huff_code_sizes[DEFL_MAX_HUFF_TABLES][DEFL_MAX_HUFF_SYMBOLS];
0268     };
0269 
0270     struct defl_sym_freq
0271     {
0272         uint16_t m_key;
0273         uint16_t m_sym_index;
0274     };
0275 
0276 #define TOOLS_FPNG_DEFL_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
0277 
0278     static defl_sym_freq* defl_radix_sort_syms(uint32_t num_syms, defl_sym_freq* pSyms0, defl_sym_freq* pSyms1)
0279     {
0280         uint32_t total_passes = 2, pass_shift, pass, i, hist[256 * 2]; defl_sym_freq* pCur_syms = pSyms0, * pNew_syms = pSyms1; TOOLS_FPNG_DEFL_CLEAR_OBJ(hist);
0281         for (i = 0; i < num_syms; i++) { uint32_t freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
0282         while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
0283         for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
0284         {
0285             const uint32_t* pHist = &hist[pass << 8];
0286             uint32_t offsets[256], cur_ofs = 0;
0287             for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
0288             for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
0289             { defl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
0290         }
0291         return pCur_syms;
0292     }
0293 
0294     // defl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
0295     static void defl_calculate_minimum_redundancy(defl_sym_freq* A, int n)
0296     {
0297         int root, leaf, next, avbl, used, dpth;
0298         if (n == 0) return; else if (n == 1) { A[0].m_key = 1; return; }
0299         A[0].m_key += A[1].m_key; root = 0; leaf = 2;
0300         for (next = 1; next < n - 1; next++)
0301         {
0302             if (leaf >= n || A[root].m_key < A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (uint16_t)next; }
0303             else A[next].m_key = A[leaf++].m_key;
0304             if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) { A[next].m_key = (uint16_t)(A[next].m_key + A[root].m_key); A[root++].m_key = (uint16_t)next; }
0305             else A[next].m_key = (uint16_t)(A[next].m_key + A[leaf++].m_key);
0306         }
0307         A[n - 2].m_key = 0; for (next = n - 3; next >= 0; next--) A[next].m_key = A[A[next].m_key].m_key + 1;
0308         avbl = 1; used = dpth = 0; root = n - 2; next = n - 1;
0309         while (avbl > 0)
0310         {
0311             while (root >= 0 && (int)A[root].m_key == dpth) { used++; root--; }
0312             while (avbl > used) { A[next--].m_key = (uint16_t)(dpth); avbl--; }
0313             avbl = 2 * used; dpth++; used = 0;
0314         }
0315     }
0316 
0317     // Limits canonical Huffman code table's max code size.
0318     enum { DEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
0319     static void defl_huffman_enforce_max_code_size(int* pNum_codes, int code_list_len, int max_code_size)
0320     {
0321         int i; uint32_t total = 0; if (code_list_len <= 1) return;
0322         for (i = max_code_size + 1; i <= DEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
0323         for (i = max_code_size; i > 0; i--) total += (((uint32_t)pNum_codes[i]) << (max_code_size - i));
0324         while (total != (1UL << max_code_size))
0325         {
0326             pNum_codes[max_code_size]--;
0327             for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
0328             total--;
0329         }
0330     }
0331 
0332     static void defl_optimize_huffman_table(defl_huff* d, int table_num, int table_len, int code_size_limit, int static_table)
0333     {
0334         int i, j, l, num_codes[1 + DEFL_MAX_SUPPORTED_HUFF_CODESIZE]; uint32_t next_code[DEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; TOOLS_FPNG_DEFL_CLEAR_OBJ(num_codes);
0335         if (static_table)
0336         {
0337             for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
0338         }
0339         else
0340         {
0341             defl_sym_freq syms0[DEFL_MAX_HUFF_SYMBOLS], syms1[DEFL_MAX_HUFF_SYMBOLS], * pSyms;
0342             int num_used_syms = 0;
0343             const uint16_t* pSym_count = &d->m_huff_count[table_num][0];
0344             for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (uint16_t)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (uint16_t)i; }
0345 
0346             pSyms = defl_radix_sort_syms(num_used_syms, syms0, syms1); defl_calculate_minimum_redundancy(pSyms, num_used_syms);
0347 
0348             for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
0349 
0350             defl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
0351 
0352             TOOLS_FPNG_DEFL_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); TOOLS_FPNG_DEFL_CLEAR_OBJ(d->m_huff_codes[table_num]);
0353             for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
0354                 for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (uint8_t)(i);
0355         }
0356 
0357         next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
0358 
0359         for (i = 0; i < table_len; i++)
0360         {
0361             uint32_t rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
0362             code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
0363             d->m_huff_codes[table_num][i] = (uint16_t)rev_code;
0364         }
0365     }
0366 
0367 #define TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
0368   if (rle_repeat_count < 3) { \
0369     d->m_huff_count[2][prev_code_size] = (uint16_t)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
0370     while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
0371   } else { \
0372     d->m_huff_count[2][16] = (uint16_t)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (uint8_t)(rle_repeat_count - 3); \
0373 } rle_repeat_count = 0; } }
0374 
0375 #define TOOLS_FPNG_DEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
0376   if (rle_z_count < 3) { \
0377     d->m_huff_count[2][0] = (uint16_t)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
0378   } else if (rle_z_count <= 10) { \
0379     d->m_huff_count[2][17] = (uint16_t)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (uint8_t)(rle_z_count - 3); \
0380   } else { \
0381     d->m_huff_count[2][18] = (uint16_t)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (uint8_t)(rle_z_count - 11); \
0382 } rle_z_count = 0; } }
0383 
0384         //G.Barrand: const in the below:
0385     static const uint8_t g_defl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
0386 
0387 #define TOOLS_FPNG_DEFL_DYN_PUT_BITS(bb, ll) \
0388 do { \
0389     uint32_t b = (bb), l = (ll); \
0390     assert((l) >= 1 && (l) <= 16); assert((b) < (1ULL << (l))); \
0391     bit_buf |= (((uint64_t)(b)) << bit_buf_size); bit_buf_size += (l); assert(bit_buf_size <= 64); \
0392     while (bit_buf_size >= 8) \
0393     { \
0394         if ((dst_ofs + 1) > dst_buf_size) \
0395             return false; \
0396         *(uint8_t*)(pDst + dst_ofs) = (uint8_t)bit_buf; \
0397         dst_ofs++; \
0398         bit_buf >>= 8; \
0399         bit_buf_size -= 8; \
0400     } \
0401 } while(0)
0402 
0403     static bool defl_start_dynamic_block(defl_huff* d, uint8_t* pDst, uint32_t& dst_ofs, uint32_t dst_buf_size, uint64_t& bit_buf, int& bit_buf_size)
0404     {
0405         int num_lit_codes, num_dist_codes, num_bit_lengths; uint32_t i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
0406         uint8_t code_sizes_to_pack[DEFL_MAX_HUFF_SYMBOLS_0 + DEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[DEFL_MAX_HUFF_SYMBOLS_0 + DEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
0407 
0408         d->m_huff_count[0][256] = 1;
0409 
0410         defl_optimize_huffman_table(d, 0, DEFL_MAX_HUFF_SYMBOLS_0, 12, FPNG_FALSE);
0411         defl_optimize_huffman_table(d, 1, DEFL_MAX_HUFF_SYMBOLS_1, 12, FPNG_FALSE);
0412 
0413         for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
0414         for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
0415 
0416         memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
0417         memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
0418         total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
0419 
0420         memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * DEFL_MAX_HUFF_SYMBOLS_2);
0421         for (i = 0; i < total_code_sizes_to_pack; i++)
0422         {
0423             uint8_t code_size = code_sizes_to_pack[i];
0424             if (!code_size)
0425             {
0426                 TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE();
0427                 if (++rle_z_count == 138) { TOOLS_FPNG_DEFL_RLE_ZERO_CODE_SIZE(); }
0428             }
0429             else
0430             {
0431                 TOOLS_FPNG_DEFL_RLE_ZERO_CODE_SIZE();
0432                 if (code_size != prev_code_size)
0433                 {
0434                     TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE();
0435                     d->m_huff_count[2][code_size] = (uint16_t)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size;
0436                 }
0437                 else if (++rle_repeat_count == 6)
0438                 {
0439                     TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE();
0440                 }
0441             }
0442             prev_code_size = code_size;
0443         }
0444         if (rle_repeat_count) { TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE(); }
0445         else { TOOLS_FPNG_DEFL_RLE_ZERO_CODE_SIZE(); }
0446 
0447         defl_optimize_huffman_table(d, 2, DEFL_MAX_HUFF_SYMBOLS_2, 7, FPNG_FALSE);
0448 
0449         // max of 2+5+5+4+18*3+(288+32)*7=2310 bits
0450         TOOLS_FPNG_DEFL_DYN_PUT_BITS(2, 2);
0451 
0452         TOOLS_FPNG_DEFL_DYN_PUT_BITS(num_lit_codes - 257, 5);
0453         TOOLS_FPNG_DEFL_DYN_PUT_BITS(num_dist_codes - 1, 5);
0454 
0455         for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][g_defl_packed_code_size_syms_swizzle[num_bit_lengths]]) break;
0456         num_bit_lengths = maximum<int>(4, (num_bit_lengths + 1)); TOOLS_FPNG_DEFL_DYN_PUT_BITS(num_bit_lengths - 4, 4);
0457         for (i = 0; (int)i < num_bit_lengths; i++) TOOLS_FPNG_DEFL_DYN_PUT_BITS(d->m_huff_code_sizes[2][g_defl_packed_code_size_syms_swizzle[i]], 3);
0458 
0459         for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
0460         {
0461             uint32_t code = packed_code_sizes[packed_code_sizes_index++]; assert(code < DEFL_MAX_HUFF_SYMBOLS_2);
0462             TOOLS_FPNG_DEFL_DYN_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
0463             if (code >= 16) TOOLS_FPNG_DEFL_DYN_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
0464         }
0465 
0466         return true;
0467     }
0468 
0469     static uint32_t write_raw_block(const uint8_t* pSrc, uint32_t src_len, uint8_t* pDst, uint32_t dst_buf_size)
0470     {
0471         if (dst_buf_size < 2)
0472             return 0;
0473 
0474         pDst[0] = 0x78;
0475         pDst[1] = 0x01;
0476 
0477         uint32_t dst_ofs = 2;
0478 
0479         uint32_t src_ofs = 0;
0480         while (src_ofs < src_len)
0481         {
0482             const uint32_t src_remaining = src_len - src_ofs;
0483             const uint32_t block_size = minimum<uint32_t>(UINT16_MAX, src_remaining);
0484             const bool final_block = (block_size == src_remaining);
0485 
0486             if ((dst_ofs + 5 + block_size) > dst_buf_size)
0487                 return 0;
0488 
0489             pDst[dst_ofs + 0] = final_block ? 1 : 0;
0490 
0491             pDst[dst_ofs + 1] = block_size & 0xFF;
0492             pDst[dst_ofs + 2] = (block_size >> 8) & 0xFF;
0493 
0494             pDst[dst_ofs + 3] = (~block_size) & 0xFF;
0495             pDst[dst_ofs + 4] = ((~block_size) >> 8) & 0xFF;
0496 
0497             memcpy(pDst + dst_ofs + 5, pSrc + src_ofs, block_size);
0498 
0499             src_ofs += block_size;
0500             dst_ofs += 5 + block_size;
0501         }
0502 
0503         uint32_t src_adler32 = fpng_adler32(pSrc, src_len, FPNG_ADLER32_INIT);
0504 
0505         for (uint32_t i = 0; i < 4; i++)
0506         {
0507             if (dst_ofs + 1 > dst_buf_size)
0508                 return 0;
0509 
0510             pDst[dst_ofs] = (uint8_t)(src_adler32 >> 24);
0511             dst_ofs++;
0512 
0513             src_adler32 <<= 8;
0514         }
0515 
0516         return dst_ofs;
0517     }
0518 
0519     static void adjust_freq32(uint32_t num_freq, uint32_t* pFreq, uint16_t* pFreq16)
0520     {
0521         uint32_t total_freq = 0;
0522         for (uint32_t i = 0; i < num_freq; i++)
0523             total_freq += pFreq[i];
0524 
0525         if (!total_freq)
0526         {
0527             memset(pFreq16, 0, num_freq * sizeof(uint16_t));
0528             return;
0529         }
0530 
0531         uint32_t total_freq16 = 0;
0532         for (uint32_t i = 0; i < num_freq; i++)
0533         {
0534             uint64_t f = pFreq[i];
0535             if (!f)
0536             {
0537                 pFreq16[i] = 0;
0538                 continue;
0539             }
0540 
0541             pFreq16[i] = (uint16_t)maximum<uint32_t>(1, (uint32_t)((f * UINT16_MAX) / total_freq));
0542 
0543             total_freq16 += pFreq16[i];
0544         }
0545 
0546         while (total_freq16 > UINT16_MAX)
0547         {
0548             total_freq16 = 0;
0549             for (uint32_t i = 0; i < num_freq; i++)
0550             {
0551                 if (pFreq[i])
0552                 {
0553                     pFreq[i] = maximum<uint32_t>(1, pFreq[i] >> 1);
0554                     total_freq16 += pFreq[i];
0555                 }
0556             }
0557         }
0558     }
0559 
0560     static uint32_t pixel_deflate_dyn_3_rle(
0561         const uint8_t* pImg, uint32_t w, uint32_t h,
0562         uint8_t* pDst, uint32_t dst_buf_size)
0563     {
0564         const uint32_t bpl = 1 + w * 3;
0565 
0566         uint64_t bit_buf = 0;
0567         int bit_buf_size = 0;
0568 
0569         uint32_t dst_ofs = 0;
0570 
0571         // zlib header
0572         TOOLS_FPNG_PUT_BITS(0x78, 8);
0573         TOOLS_FPNG_PUT_BITS(0x01, 8);
0574 
0575         // write BFINAL bit
0576         TOOLS_FPNG_PUT_BITS(1, 1);
0577 
0578         std::vector<uint32_t> codes((w + 1) * h);
0579         uint32_t* pDst_codes = codes.data();
0580 
0581         uint32_t lit_freq[DEFL_MAX_HUFF_SYMBOLS_0];
0582         memset(lit_freq, 0, sizeof(lit_freq));
0583         
0584         const uint8_t* pSrc = pImg;
0585         uint32_t src_ofs = 0;
0586 
0587         uint32_t src_adler32 = fpng_adler32(pImg, bpl * h, FPNG_ADLER32_INIT);
0588 
0589         const uint32_t dist_sym = g_defl_small_dist_sym[3 - 1];
0590                 
0591         for (uint32_t y = 0; y < h; y++)
0592         {
0593             const uint32_t end_src_ofs = src_ofs + bpl;
0594 
0595             const uint32_t filter_lit = pSrc[src_ofs++];
0596             *pDst_codes++ = 1 | (filter_lit << 8);
0597             lit_freq[filter_lit]++;
0598 
0599             uint32_t prev_lits;
0600 
0601             {
0602                 uint32_t lits = READ_RGB_PIXEL(pSrc + src_ofs);
0603 
0604                 *pDst_codes++ = lits << 8;
0605 
0606                 lit_freq[lits & 0xFF]++;
0607                 lit_freq[(lits >> 8) & 0xFF]++;
0608                 lit_freq[lits >> 16]++;
0609 
0610                 src_ofs += 3;
0611 
0612                 prev_lits = lits;
0613             }
0614 
0615             while (src_ofs < end_src_ofs)
0616             {
0617                 uint32_t lits = READ_RGB_PIXEL(pSrc + src_ofs);
0618 
0619                 if (lits == prev_lits)
0620                 {
0621                     uint32_t match_len = 3;
0622                     uint32_t max_match_len = minimum<int>(255, (int)(end_src_ofs - src_ofs));
0623 
0624                     while (match_len < max_match_len)
0625                     {
0626                         if (READ_RGB_PIXEL(pSrc + src_ofs + match_len) != lits)
0627                             break;
0628                         match_len += 3;
0629                     }
0630                                         
0631                     *pDst_codes++ = match_len - 1;
0632 
0633                     uint32_t adj_match_len = match_len - 3;
0634 
0635                     lit_freq[g_defl_len_sym[adj_match_len]]++;
0636                     
0637                     src_ofs += match_len;
0638                 }
0639                 else
0640                 {
0641                     *pDst_codes++ = lits << 8;
0642 
0643                     lit_freq[lits & 0xFF]++;
0644                     lit_freq[(lits >> 8) & 0xFF]++;
0645                     lit_freq[lits >> 16]++;
0646 
0647                     prev_lits = lits;
0648 
0649                     src_ofs += 3;
0650                 }
0651 
0652             } // while (src_ofs < end_src_ofs)
0653 
0654         } // y
0655 
0656         assert(src_ofs == h * bpl);
0657         const uint32_t total_codes = (uint32_t)(pDst_codes - codes.data());
0658         assert(total_codes <= codes.size());
0659                                 
0660         defl_huff dh;
0661         
0662         lit_freq[256] = 1;
0663 
0664         adjust_freq32(DEFL_MAX_HUFF_SYMBOLS_0, lit_freq, &dh.m_huff_count[0][0]);
0665 
0666         memset(&dh.m_huff_count[1][0], 0, sizeof(dh.m_huff_count[1][0]) * DEFL_MAX_HUFF_SYMBOLS_1);
0667         dh.m_huff_count[1][dist_sym] = 1;
0668         dh.m_huff_count[1][dist_sym + 1] = 1; // to workaround a bug in wuffs decoder
0669 
0670         if (!defl_start_dynamic_block(&dh, pDst, dst_ofs, dst_buf_size, bit_buf, bit_buf_size))
0671             return 0;
0672 
0673         assert(bit_buf_size <= 7);
0674         assert(dh.m_huff_codes[1][dist_sym] == 0 && dh.m_huff_code_sizes[1][dist_sym] == 1);
0675                 
0676         for (uint32_t i = 0; i < total_codes; i++)
0677         {
0678             uint32_t c = codes[i];
0679 
0680             uint32_t c_type = c & 0xFF;
0681             if (c_type == 0)
0682             {
0683                 uint32_t lits = c >> 8;
0684 
0685                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits & 0xFF], dh.m_huff_code_sizes[0][lits & 0xFF]);
0686                 lits >>= 8;
0687 
0688                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits & 0xFF], dh.m_huff_code_sizes[0][lits & 0xFF]);
0689                 lits >>= 8;
0690 
0691                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits], dh.m_huff_code_sizes[0][lits]);
0692             }
0693             else if (c_type == 1)
0694             {
0695                 uint32_t lit = c >> 8;
0696                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lit], dh.m_huff_code_sizes[0][lit]);
0697             }
0698             else
0699             {
0700                 uint32_t match_len = c_type + 1;
0701 
0702                 uint32_t adj_match_len = match_len - 3;
0703                 
0704                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][g_defl_len_sym[adj_match_len]], dh.m_huff_code_sizes[0][g_defl_len_sym[adj_match_len]]);
0705                 TOOLS_FPNG_PUT_BITS(adj_match_len & g_bitmasks[g_defl_len_extra[adj_match_len]], g_defl_len_extra[adj_match_len] + 1); // up to 6 bits, +1 for the match distance Huff code which is always 0
0706 
0707                 // no need to write the distance code, it's always 0
0708                 //TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[1][dist_sym], dh.m_huff_code_sizes[1][dist_sym]);
0709             }
0710 
0711             // up to 55 bits
0712             TOOLS_FPNG_PUT_BITS_FLUSH;
0713         }
0714 
0715         TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][256], dh.m_huff_code_sizes[0][256]);
0716 
0717         TOOLS_FPNG_PUT_BITS_FORCE_FLUSH;
0718 
0719         // Write zlib adler32
0720         for (uint32_t i = 0; i < 4; i++)
0721         {
0722             if ((dst_ofs + 1) > dst_buf_size)
0723                 return 0;
0724             *(uint8_t*)(pDst + dst_ofs) = (uint8_t)(src_adler32 >> 24);
0725             dst_ofs++;
0726 
0727             src_adler32 <<= 8;
0728         }
0729 
0730         return dst_ofs;
0731     }
0732 
0733     static uint32_t pixel_deflate_dyn_3_rle_one_pass(
0734         const uint8_t* pImg, uint32_t w, uint32_t h,
0735         uint8_t* pDst, uint32_t dst_buf_size)
0736     {
0737         const uint32_t bpl = 1 + w * 3;
0738 
0739         if (dst_buf_size < sizeof(g_dyn_huff_3))
0740             return false;
0741         memcpy(pDst, g_dyn_huff_3, sizeof(g_dyn_huff_3));
0742         uint32_t dst_ofs = sizeof(g_dyn_huff_3);
0743 
0744         uint64_t bit_buf = DYN_HUFF_3_BITBUF;
0745         int bit_buf_size = DYN_HUFF_3_BITBUF_SIZE;
0746 
0747         const uint8_t* pSrc = pImg;
0748         uint32_t src_ofs = 0;
0749 
0750         uint32_t src_adler32 = fpng_adler32(pImg, bpl * h, FPNG_ADLER32_INIT);
0751 
0752         for (uint32_t y = 0; y < h; y++)
0753         {
0754             const uint32_t end_src_ofs = src_ofs + bpl;
0755 
0756             const uint32_t filter_lit = pSrc[src_ofs++];
0757             TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[filter_lit].m_code, g_dyn_huff_3_codes[filter_lit].m_code_size);
0758 
0759             uint32_t prev_lits;
0760 
0761             {
0762                 uint32_t lits = READ_RGB_PIXEL(pSrc + src_ofs);
0763 
0764                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[lits & 0xFF].m_code, g_dyn_huff_3_codes[lits & 0xFF].m_code_size);
0765                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[(lits >> 8) & 0xFF].m_code, g_dyn_huff_3_codes[(lits >> 8) & 0xFF].m_code_size);
0766                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[(lits >> 16)].m_code, g_dyn_huff_3_codes[(lits >> 16)].m_code_size);
0767 
0768                 src_ofs += 3;
0769             
0770                 prev_lits = lits;
0771             }
0772 
0773             TOOLS_FPNG_PUT_BITS_FLUSH;
0774 
0775             while (src_ofs < end_src_ofs)
0776             {
0777                 uint32_t lits = READ_RGB_PIXEL(pSrc + src_ofs);
0778 
0779                 if (lits == prev_lits)
0780                 {
0781                     uint32_t match_len = 3;
0782                     uint32_t max_match_len = minimum<int>(255, (int)(end_src_ofs - src_ofs));
0783 
0784                     while (match_len < max_match_len)
0785                     {
0786                         if (READ_RGB_PIXEL(pSrc + src_ofs + match_len) != lits)
0787                             break;
0788                         match_len += 3;
0789                     }
0790                                         
0791                     uint32_t adj_match_len = match_len - 3;
0792 
0793                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[g_defl_len_sym[adj_match_len]].m_code, g_dyn_huff_3_codes[g_defl_len_sym[adj_match_len]].m_code_size);
0794                     TOOLS_FPNG_PUT_BITS(adj_match_len & g_bitmasks[g_defl_len_extra[adj_match_len]], g_defl_len_extra[adj_match_len] + 1); // up to 6 bits, +1 for the match distance Huff code which is always 0
0795 
0796                     src_ofs += match_len;
0797                 }
0798                 else
0799                 {
0800                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[lits & 0xFF].m_code, g_dyn_huff_3_codes[lits & 0xFF].m_code_size);
0801                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[(lits >> 8) & 0xFF].m_code, g_dyn_huff_3_codes[(lits >> 8) & 0xFF].m_code_size);
0802                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[(lits >> 16)].m_code, g_dyn_huff_3_codes[(lits >> 16)].m_code_size);
0803                     
0804                     prev_lits = lits;
0805 
0806                     src_ofs += 3;
0807                 }
0808 
0809                 TOOLS_FPNG_PUT_BITS_FLUSH;
0810 
0811             } // while (src_ofs < end_src_ofs)
0812 
0813         } // y
0814 
0815         assert(src_ofs == h * bpl);
0816         
0817         assert(bit_buf_size <= 7);
0818 
0819         TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_3_codes[256].m_code, g_dyn_huff_3_codes[256].m_code_size);
0820 
0821         TOOLS_FPNG_PUT_BITS_FORCE_FLUSH;
0822 
0823         // Write zlib adler32
0824         for (uint32_t i = 0; i < 4; i++)
0825         {
0826             if ((dst_ofs + 1) > dst_buf_size)
0827                 return 0;
0828             *(uint8_t*)(pDst + dst_ofs) = (uint8_t)(src_adler32 >> 24);
0829             dst_ofs++;
0830 
0831             src_adler32 <<= 8;
0832         }
0833 
0834         return dst_ofs;
0835     }
0836 
0837     static uint32_t pixel_deflate_dyn_4_rle(
0838         const uint8_t* pImg, uint32_t w, uint32_t h,
0839         uint8_t* pDst, uint32_t dst_buf_size)
0840     {
0841         const uint32_t bpl = 1 + w * 4;
0842 
0843         uint64_t bit_buf = 0;
0844         int bit_buf_size = 0;
0845 
0846         uint32_t dst_ofs = 0;
0847 
0848         // zlib header
0849         TOOLS_FPNG_PUT_BITS(0x78, 8);
0850         TOOLS_FPNG_PUT_BITS(0x01, 8);
0851 
0852         // write BFINAL bit
0853         TOOLS_FPNG_PUT_BITS(1, 1);
0854 
0855         std::vector<uint64_t> codes;
0856         codes.resize((w + 1) * h);
0857         uint64_t* pDst_codes = codes.data();
0858 
0859         uint32_t lit_freq[DEFL_MAX_HUFF_SYMBOLS_0];
0860         memset(lit_freq, 0, sizeof(lit_freq));
0861 
0862         const uint8_t* pSrc = pImg;
0863         uint32_t src_ofs = 0;
0864 
0865         uint32_t src_adler32 = fpng_adler32(pImg, bpl * h, FPNG_ADLER32_INIT);
0866 
0867         const uint32_t dist_sym = g_defl_small_dist_sym[4 - 1];
0868 
0869         for (uint32_t y = 0; y < h; y++)
0870         {
0871             const uint32_t end_src_ofs = src_ofs + bpl;
0872 
0873             const uint32_t filter_lit = pSrc[src_ofs++];
0874             *pDst_codes++ = 1 | (filter_lit << 8);
0875             lit_freq[filter_lit]++;
0876 
0877             uint32_t prev_lits;
0878             {
0879                 uint32_t lits = READ_LE32(pSrc + src_ofs);
0880 
0881                 *pDst_codes++ = (uint64_t)lits << 8;
0882 
0883                 lit_freq[lits & 0xFF]++;
0884                 lit_freq[(lits >> 8) & 0xFF]++;
0885                 lit_freq[(lits >> 16) & 0xFF]++;
0886                 lit_freq[lits >> 24]++;
0887 
0888                 src_ofs += 4;
0889                 
0890                 prev_lits = lits;
0891             }
0892 
0893             while (src_ofs < end_src_ofs)
0894             {
0895                 uint32_t lits = READ_LE32(pSrc + src_ofs);
0896 
0897                 if (lits == prev_lits)
0898                 {
0899                     uint32_t match_len = 4;
0900                     uint32_t max_match_len = minimum<int>(252, (int)(end_src_ofs - src_ofs));
0901 
0902                     while (match_len < max_match_len)
0903                     {
0904                         if (READ_LE32(pSrc + src_ofs + match_len) != lits)
0905                             break;
0906                         match_len += 4;
0907                     }
0908                                         
0909                     *pDst_codes++ = match_len - 1;
0910 
0911                     uint32_t adj_match_len = match_len - 3;
0912 
0913                     lit_freq[g_defl_len_sym[adj_match_len]]++;
0914                     
0915                     src_ofs += match_len;
0916                 }
0917                 else
0918                 {
0919                     *pDst_codes++ = (uint64_t)lits << 8;
0920 
0921                     lit_freq[lits & 0xFF]++;
0922                     lit_freq[(lits >> 8) & 0xFF]++;
0923                     lit_freq[(lits >> 16) & 0xFF]++;
0924                     lit_freq[lits >> 24]++;
0925                     
0926                     prev_lits = lits;
0927 
0928                     src_ofs += 4;
0929                 }
0930 
0931             } // while (src_ofs < end_src_ofs)
0932 
0933         } // y
0934 
0935         assert(src_ofs == h * bpl);
0936         const uint32_t total_codes = (uint32_t)(pDst_codes - codes.data());
0937         assert(total_codes <= codes.size());
0938                         
0939         defl_huff dh;
0940         
0941         lit_freq[256] = 1;
0942 
0943         adjust_freq32(DEFL_MAX_HUFF_SYMBOLS_0, lit_freq, &dh.m_huff_count[0][0]);
0944         
0945         memset(&dh.m_huff_count[1][0], 0, sizeof(dh.m_huff_count[1][0]) * DEFL_MAX_HUFF_SYMBOLS_1);
0946         dh.m_huff_count[1][dist_sym] = 1;
0947         dh.m_huff_count[1][dist_sym + 1] = 1; // to workaround a bug in wuffs decoder
0948 
0949         if (!defl_start_dynamic_block(&dh, pDst, dst_ofs, dst_buf_size, bit_buf, bit_buf_size))
0950             return 0;
0951 
0952         assert(bit_buf_size <= 7);
0953         assert(dh.m_huff_codes[1][dist_sym] == 0 && dh.m_huff_code_sizes[1][dist_sym] == 1);
0954 
0955         for (uint32_t i = 0; i < total_codes; i++)
0956         {
0957             uint64_t c = codes[i];
0958 
0959             uint32_t c_type = (uint32_t)(c & 0xFF);
0960             if (c_type == 0)
0961             {
0962                 uint32_t lits = (uint32_t)(c >> 8);
0963 
0964                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits & 0xFF], dh.m_huff_code_sizes[0][lits & 0xFF]);
0965                 lits >>= 8;
0966 
0967                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits & 0xFF], dh.m_huff_code_sizes[0][lits & 0xFF]);
0968                 lits >>= 8;
0969 
0970                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits & 0xFF], dh.m_huff_code_sizes[0][lits & 0xFF]);
0971                 lits >>= 8;
0972 
0973                 if (bit_buf_size >= 49)
0974                 {
0975                     TOOLS_FPNG_PUT_BITS_FLUSH;
0976                 }
0977 
0978                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lits], dh.m_huff_code_sizes[0][lits]);
0979             }
0980             else if (c_type == 1)
0981             {
0982                 uint32_t lit = (uint32_t)(c >> 8);
0983                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][lit], dh.m_huff_code_sizes[0][lit]);
0984             }
0985             else
0986             {
0987                 uint32_t match_len = c_type + 1;
0988 
0989                 uint32_t adj_match_len = match_len - 3;
0990                 
0991                 TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][g_defl_len_sym[adj_match_len]], dh.m_huff_code_sizes[0][g_defl_len_sym[adj_match_len]]);
0992                 TOOLS_FPNG_PUT_BITS(adj_match_len & g_bitmasks[g_defl_len_extra[adj_match_len]], g_defl_len_extra[adj_match_len] + 1); // up to 6 bits, +1 for the match distance Huff code which is always 0
0993 
0994                 // no need to write the distance code, it's always 0
0995             }
0996 
0997             // up to 55 bits
0998             TOOLS_FPNG_PUT_BITS_FLUSH;
0999         }
1000 
1001         TOOLS_FPNG_PUT_BITS_CZ(dh.m_huff_codes[0][256], dh.m_huff_code_sizes[0][256]);
1002 
1003         TOOLS_FPNG_PUT_BITS_FORCE_FLUSH;
1004 
1005         // Write zlib adler32
1006         for (uint32_t i = 0; i < 4; i++)
1007         {
1008             if ((dst_ofs + 1) > dst_buf_size)
1009                 return 0;
1010             *(uint8_t*)(pDst + dst_ofs) = (uint8_t)(src_adler32 >> 24);
1011             dst_ofs++;
1012 
1013             src_adler32 <<= 8;
1014         }
1015 
1016         return dst_ofs;
1017     }
1018 
1019     static uint32_t pixel_deflate_dyn_4_rle_one_pass(
1020         const uint8_t* pImg, uint32_t w, uint32_t h,
1021         uint8_t* pDst, uint32_t dst_buf_size)
1022     {
1023         const uint32_t bpl = 1 + w * 4;
1024 
1025         if (dst_buf_size < sizeof(g_dyn_huff_4))
1026             return false;
1027         memcpy(pDst, g_dyn_huff_4, sizeof(g_dyn_huff_4));
1028         uint32_t dst_ofs = sizeof(g_dyn_huff_4);
1029 
1030         uint64_t bit_buf = DYN_HUFF_4_BITBUF;
1031         int bit_buf_size = DYN_HUFF_4_BITBUF_SIZE;
1032 
1033         const uint8_t* pSrc = pImg;
1034         uint32_t src_ofs = 0;
1035 
1036         uint32_t src_adler32 = fpng_adler32(pImg, bpl * h, FPNG_ADLER32_INIT);
1037 
1038         for (uint32_t y = 0; y < h; y++)
1039         {
1040             const uint32_t end_src_ofs = src_ofs + bpl;
1041 
1042             const uint32_t filter_lit = pSrc[src_ofs++];
1043             TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[filter_lit].m_code, g_dyn_huff_4_codes[filter_lit].m_code_size);
1044 
1045             TOOLS_FPNG_PUT_BITS_FLUSH;
1046 
1047             uint32_t prev_lits;
1048             {
1049                 uint32_t lits = READ_LE32(pSrc + src_ofs);
1050 
1051                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[lits & 0xFF].m_code, g_dyn_huff_4_codes[lits & 0xFF].m_code_size);
1052                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 8) & 0xFF].m_code, g_dyn_huff_4_codes[(lits >> 8) & 0xFF].m_code_size);
1053                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 16) & 0xFF].m_code, g_dyn_huff_4_codes[(lits >> 16) & 0xFF].m_code_size);
1054 
1055                 if (bit_buf_size >= 49)
1056                 {
1057                     TOOLS_FPNG_PUT_BITS_FLUSH;
1058                 }
1059                 
1060                 TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 24)].m_code, g_dyn_huff_4_codes[(lits >> 24)].m_code_size);
1061 
1062                 src_ofs += 4;
1063                 
1064                 prev_lits = lits;
1065             }
1066 
1067             TOOLS_FPNG_PUT_BITS_FLUSH;
1068 
1069             while (src_ofs < end_src_ofs)
1070             {
1071                 uint32_t lits = READ_LE32(pSrc + src_ofs);
1072                                 
1073                 if (lits == prev_lits)
1074                 {
1075                     uint32_t match_len = 4;
1076                     uint32_t max_match_len = minimum<int>(252, (int)(end_src_ofs - src_ofs));
1077 
1078                     while (match_len < max_match_len)
1079                     {
1080                         if (READ_LE32(pSrc + src_ofs + match_len) != lits)
1081                             break;
1082                         match_len += 4;
1083                     }
1084 
1085                     uint32_t adj_match_len = match_len - 3;
1086 
1087                     const uint32_t match_code_bits = g_dyn_huff_4_codes[g_defl_len_sym[adj_match_len]].m_code_size;
1088                     const uint32_t len_extra_bits = g_defl_len_extra[adj_match_len];
1089 
1090                     if (match_len == 4)
1091                     {
1092                         // This check is optional - see if just encoding 4 literals would be cheaper than using a short match.
1093                         uint32_t lit_bits = g_dyn_huff_4_codes[lits & 0xFF].m_code_size + g_dyn_huff_4_codes[(lits >> 8) & 0xFF].m_code_size + 
1094                             g_dyn_huff_4_codes[(lits >> 16) & 0xFF].m_code_size + g_dyn_huff_4_codes[(lits >> 24)].m_code_size;
1095                         
1096                         if ((match_code_bits + len_extra_bits + 1) > lit_bits)
1097                             goto do_literals;
1098                     }
1099 
1100                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[g_defl_len_sym[adj_match_len]].m_code, match_code_bits);
1101                     TOOLS_FPNG_PUT_BITS(adj_match_len & g_bitmasks[g_defl_len_extra[adj_match_len]], len_extra_bits + 1); // up to 6 bits, +1 for the match distance Huff code which is always 0
1102 
1103                     src_ofs += match_len;
1104                 }
1105                 else
1106                 {
1107 do_literals:
1108                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[lits & 0xFF].m_code, g_dyn_huff_4_codes[lits & 0xFF].m_code_size);
1109                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 8) & 0xFF].m_code, g_dyn_huff_4_codes[(lits >> 8) & 0xFF].m_code_size);
1110                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 16) & 0xFF].m_code, g_dyn_huff_4_codes[(lits >> 16) & 0xFF].m_code_size);
1111 
1112                     if (bit_buf_size >= 49)
1113                     {
1114                         TOOLS_FPNG_PUT_BITS_FLUSH;
1115                     }
1116 
1117                     TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[(lits >> 24)].m_code, g_dyn_huff_4_codes[(lits >> 24)].m_code_size);
1118 
1119                     src_ofs += 4;
1120                     
1121                     prev_lits = lits;
1122                 }
1123 
1124                 TOOLS_FPNG_PUT_BITS_FLUSH;
1125 
1126             } // while (src_ofs < end_src_ofs)
1127 
1128         } // y
1129 
1130         assert(src_ofs == h * bpl);
1131 
1132         assert(bit_buf_size <= 7);
1133 
1134         TOOLS_FPNG_PUT_BITS_CZ(g_dyn_huff_4_codes[256].m_code, g_dyn_huff_4_codes[256].m_code_size);
1135 
1136         TOOLS_FPNG_PUT_BITS_FORCE_FLUSH;
1137 
1138         // Write zlib adler32
1139         for (uint32_t i = 0; i < 4; i++)
1140         {
1141             if ((dst_ofs + 1) > dst_buf_size)
1142                 return 0;
1143             *(uint8_t*)(pDst + dst_ofs) = (uint8_t)(src_adler32 >> 24);
1144             dst_ofs++;
1145 
1146             src_adler32 <<= 8;
1147         }
1148 
1149         return dst_ofs;
1150     }
1151 
1152     static void vector_append(std::vector<uint8_t>& buf, const void* pData, size_t len)
1153     {
1154         if (len)
1155         {
1156             size_t l = buf.size();
1157             buf.resize(l + len);
1158             memcpy(buf.data() + l, pData, len);
1159         }
1160     }
1161         
1162     static void apply_filter(uint32_t filter, int w, int h, uint32_t num_chans, uint32_t bpl, const uint8_t* pSrc, const uint8_t* pPrev_src, uint8_t* pDst)
1163     {
1164         (void)h;
1165 
1166         switch (filter)
1167         {
1168         case 0:
1169         {
1170             *pDst++ = 0;
1171 
1172             memcpy(pDst, pSrc, bpl);
1173             break;
1174         }
1175         case 2:
1176         {
1177             assert(pPrev_src);
1178 
1179             // Previous scanline
1180             *pDst++ = 2;
1181 
1182             {
1183                 if (num_chans == 3)
1184                 {
1185                     for (uint32_t x = 0; x < (uint32_t)w; x++)
1186                     {
1187                         pDst[0] = (uint8_t)(pSrc[0] - pPrev_src[0]);
1188                         pDst[1] = (uint8_t)(pSrc[1] - pPrev_src[1]);
1189                         pDst[2] = (uint8_t)(pSrc[2] - pPrev_src[2]);
1190 
1191                         pSrc += 3;
1192                         pPrev_src += 3;
1193                         pDst += 3;
1194                     }
1195                 }
1196                 else
1197                 {
1198                     for (uint32_t x = 0; x < (uint32_t)w; x++)
1199                     {
1200                         pDst[0] = (uint8_t)(pSrc[0] - pPrev_src[0]);
1201                         pDst[1] = (uint8_t)(pSrc[1] - pPrev_src[1]);
1202                         pDst[2] = (uint8_t)(pSrc[2] - pPrev_src[2]);
1203                         pDst[3] = (uint8_t)(pSrc[3] - pPrev_src[3]);
1204 
1205                         pSrc += 4;
1206                         pPrev_src += 4;
1207                         pDst += 4;
1208                     }
1209                 }
1210             }
1211 
1212             break;
1213         }
1214         default:
1215             assert(0);
1216             break;
1217         }
1218     }
1219 
1220     inline bool fpng_encode_image_to_memory(const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans, std::vector<uint8_t>& out_buf, uint32_t flags)
1221     {
1222         if (!endian_check())
1223         {
1224             assert(0);
1225             return false;
1226         }
1227 
1228         if ((w < 1) || (h < 1) || (w * (uint64_t)h > UINT32_MAX) || (w > FPNG_MAX_SUPPORTED_DIM) || (h > FPNG_MAX_SUPPORTED_DIM))
1229         {
1230             assert(0);
1231             return false;
1232         }
1233 
1234         if ((num_chans != 3) && (num_chans != 4))
1235         {
1236             assert(0);
1237             return false;
1238         }
1239 
1240         int i, bpl = w * num_chans;
1241         uint32_t y;
1242 
1243         std::vector<uint8_t> temp_buf;
1244         temp_buf.resize((bpl + 1) * h + 7);
1245         uint32_t temp_buf_ofs = 0;
1246 
1247         for (y = 0; y < h; ++y)
1248         {
1249             const uint8_t* pSrc = (uint8_t*)pImage + y * bpl;
1250             const uint8_t* pPrev_src = y ? ((uint8_t*)pImage + (y - 1) * bpl) : NULL/*nullptr*/;
1251 
1252             uint8_t* pDst = &temp_buf[temp_buf_ofs];
1253 
1254             apply_filter(y ? 2 : 0, w, h, num_chans, bpl, pSrc, pPrev_src, pDst);
1255 
1256             temp_buf_ofs += 1 + bpl;
1257         }
1258 
1259         const uint32_t PNG_HEADER_SIZE = 58;
1260                 
1261         uint32_t out_ofs = PNG_HEADER_SIZE;
1262                 
1263         out_buf.resize((out_ofs + (bpl + 1) * h + 7) & ~7);
1264 
1265         uint32_t defl_size = 0;
1266         if ((flags & FPNG_FORCE_UNCOMPRESSED) == 0)
1267         {
1268             if (num_chans == 3)
1269             {
1270                 if (flags & FPNG_ENCODE_SLOWER)
1271                     defl_size = pixel_deflate_dyn_3_rle(temp_buf.data(), w, h, &out_buf[out_ofs], (uint32_t)out_buf.size() - out_ofs);
1272                 else
1273                     defl_size = pixel_deflate_dyn_3_rle_one_pass(temp_buf.data(), w, h, &out_buf[out_ofs], (uint32_t)out_buf.size() - out_ofs);
1274             }
1275             else
1276             {
1277                 if (flags & FPNG_ENCODE_SLOWER)
1278                     defl_size = pixel_deflate_dyn_4_rle(temp_buf.data(), w, h, &out_buf[out_ofs], (uint32_t)out_buf.size() - out_ofs);
1279                 else
1280                     defl_size = pixel_deflate_dyn_4_rle_one_pass(temp_buf.data(), w, h, &out_buf[out_ofs], (uint32_t)out_buf.size() - out_ofs);
1281             }
1282         }
1283 
1284         uint32_t zlib_size = defl_size;
1285         
1286         if (!defl_size)
1287         {
1288             // Dynamic block failed to compress - fall back to uncompressed blocks, filter 0.
1289 
1290             temp_buf_ofs = 0;
1291 
1292             for (y = 0; y < h; ++y)
1293             {
1294                 const uint8_t* pSrc = (uint8_t*)pImage + y * bpl;
1295 
1296                 uint8_t* pDst = &temp_buf[temp_buf_ofs];
1297 
1298                 apply_filter(0, w, h, num_chans, bpl, pSrc, NULL/*nullptr*/, pDst);
1299 
1300                 temp_buf_ofs += 1 + bpl;
1301             }
1302 
1303             assert(temp_buf_ofs <= temp_buf.size());
1304                         
1305             out_buf.resize(out_ofs + 6 + temp_buf_ofs + ((temp_buf_ofs + 65534) / 65535) * 5);
1306 
1307             uint32_t raw_size = write_raw_block(temp_buf.data(), (uint32_t)temp_buf_ofs, out_buf.data() + out_ofs, (uint32_t)out_buf.size() - out_ofs);
1308             if (!raw_size)
1309             {
1310                 // Somehow we miscomputed the size of the output buffer.
1311                 assert(0);
1312                 return false;
1313             }
1314 
1315             zlib_size = raw_size;
1316         }
1317         
1318         assert((out_ofs + zlib_size) <= out_buf.size());
1319 
1320         out_buf.resize(out_ofs + zlib_size);
1321 
1322         const uint32_t idat_len = (uint32_t)out_buf.size() - PNG_HEADER_SIZE;
1323 
1324         // Write real PNG header, fdEC chunk, and the beginning of the IDAT chunk
1325         {
1326             static const uint8_t s_color_type[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
1327 
1328             uint8_t pnghdr[58] = { 
1329                 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,   // PNG sig
1330                 0x00,0x00,0x00,0x0d, 'I','H','D','R',  // IHDR chunk len, type
1331                 0,0,(uint8_t)(w >> 8),(uint8_t)w, // width
1332                 0,0,(uint8_t)(h >> 8),(uint8_t)h, // height
1333                 8,   //bit_depth
1334                 s_color_type[num_chans], // color_type
1335                 0, // compression
1336                 0, // filter
1337                 0, // interlace
1338                 0, 0, 0, 0, // IHDR crc32
1339                 0, 0, 0, 5, 'f', 'd', 'E', 'C', 82, 36, 147, 227, FPNG_FDEC_VERSION,   0xE5, 0xAB, 0x62, 0x99, // our custom private, ancillary, do not copy, fdEC chunk
1340               (uint8_t)(idat_len >> 24),(uint8_t)(idat_len >> 16),(uint8_t)(idat_len >> 8),(uint8_t)idat_len, 'I','D','A','T' // IDATA chunk len, type
1341             }; 
1342 
1343             // Compute IHDR CRC32
1344             uint32_t c = (uint32_t)fpng_crc32(pnghdr + 12, 17, FPNG_CRC32_INIT);
1345             for (i = 0; i < 4; ++i, c <<= 8)
1346                 ((uint8_t*)(pnghdr + 29))[i] = (uint8_t)(c >> 24);
1347 
1348             memcpy(out_buf.data(), pnghdr, PNG_HEADER_SIZE);
1349         }
1350 
1351         // Write IDAT chunk's CRC32 and a 0 length IEND chunk
1352         vector_append(out_buf, "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16); // IDAT CRC32, followed by the IEND chunk
1353 
1354         // Compute IDAT crc32
1355         uint32_t c = (uint32_t)fpng_crc32(out_buf.data() + PNG_HEADER_SIZE - 4, idat_len + 4, FPNG_CRC32_INIT);
1356         
1357         for (i = 0; i < 4; ++i, c <<= 8)
1358             (out_buf.data() + out_buf.size() - 16)[i] = (uint8_t)(c >> 24);
1359                 
1360         return true;
1361     }
1362 
1363     inline bool fpng_encode_image_to_file(const char* pFilename, const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans, uint32_t flags)
1364     {
1365         std::vector<uint8_t> out_buf;
1366         if (!fpng_encode_image_to_memory(pImage, w, h, num_chans, out_buf, flags))
1367             return false;
1368 
1369                 FILE* pFile = fopen(pFilename, "wb");
1370                 if (!pFile) return false;
1371 
1372         if (fwrite(out_buf.data(), 1, out_buf.size(), pFile) != out_buf.size())
1373         {
1374             fclose(pFile);
1375             return false;
1376         }
1377 
1378         return (fclose(pFile) != EOF);
1379     }
1380 
1381     // Decompression
1382 
1383     const uint32_t FPNG_DECODER_TABLE_BITS = 12;
1384     const uint32_t FPNG_DECODER_TABLE_SIZE = 1 << FPNG_DECODER_TABLE_BITS;
1385 
1386     static bool build_decoder_table(uint32_t num_syms, uint8_t* pCode_sizes, uint32_t* pTable)
1387     {
1388         uint32_t num_codes[16];
1389 
1390         memset(num_codes, 0, sizeof(num_codes));
1391         for (uint32_t i = 0; i < num_syms; i++)
1392         {
1393                 assert(uint32_t(pCode_sizes[i]) <= FPNG_DECODER_TABLE_SIZE); //G.Barrand: uint32_t cast.
1394             num_codes[pCode_sizes[i]]++;
1395         }
1396 
1397         uint32_t next_code[17];
1398         next_code[0] = next_code[1] = 0;
1399         uint32_t total = 0;
1400         for (uint32_t i = 1; i <= 15; i++)
1401             next_code[i + 1] = (uint32_t)(total = ((total + ((uint32_t)num_codes[i])) << 1));
1402 
1403         if (total != 0x10000)
1404         {
1405             uint32_t j = 0;
1406 
1407             for (uint32_t i = 15; i != 0; i--)
1408                 if ((j += num_codes[i]) > 1)
1409                     return false;
1410             
1411             if (j != 1)
1412                 return false;
1413         }
1414 
1415         uint32_t rev_codes[DEFL_MAX_HUFF_SYMBOLS];
1416 
1417         for (uint32_t i = 0; i < num_syms; i++)
1418             rev_codes[i] = next_code[pCode_sizes[i]]++;
1419 
1420         memset(pTable, 0, sizeof(uint32_t) * FPNG_DECODER_TABLE_SIZE);
1421 
1422         for (uint32_t i = 0; i < num_syms; i++)
1423         {
1424             const uint32_t code_size = pCode_sizes[i];
1425             if (!code_size)
1426                 continue;
1427 
1428             uint32_t old_code = rev_codes[i], new_code = 0;
1429             for (uint32_t j = code_size; j != 0; j--)
1430             {
1431                 new_code = (new_code << 1) | (old_code & 1);
1432                 old_code >>= 1;
1433             }
1434 
1435             uint32_t j = 1 << code_size;
1436 
1437             while (new_code < FPNG_DECODER_TABLE_SIZE)
1438             {
1439                 pTable[new_code] = i | (code_size << 9);
1440                 new_code += j;
1441             }
1442         }
1443 
1444         return true;
1445     }
1446 
1447     static const uint16_t g_run_len3_to_4[259] = 
1448     {
1449         0,
1450         0, 0, 4, 0, 0, 8, 0, 0, 12, 0, 0, 16, 0, 0, 20, 0, 0, 24, 0, 0, 28, 0, 0,
1451         32, 0, 0, 36, 0, 0, 40, 0, 0, 44, 0, 0, 48, 0, 0, 52, 0, 0, 56, 0, 0,
1452         60, 0, 0, 64, 0, 0, 68, 0, 0, 72, 0, 0, 76, 0, 0, 80, 0, 0, 84, 0, 0,
1453         88, 0, 0, 92, 0, 0, 96, 0, 0, 100, 0, 0, 104, 0, 0, 108, 0, 0, 112, 0, 0,
1454         116, 0, 0, 120, 0, 0, 124, 0, 0, 128, 0, 0, 132, 0, 0, 136, 0, 0, 140, 0, 0,
1455         144, 0, 0, 148, 0, 0, 152, 0, 0, 156, 0, 0, 160, 0, 0, 164, 0, 0, 168, 0, 0,
1456         172, 0, 0, 176, 0, 0, 180, 0, 0, 184, 0, 0, 188, 0, 0, 192, 0, 0, 196, 0, 0,
1457         200, 0, 0, 204, 0, 0, 208, 0, 0, 212, 0, 0, 216, 0, 0, 220, 0, 0, 224, 0, 0,
1458         228, 0, 0, 232, 0, 0, 236, 0, 0, 240, 0, 0, 244, 0, 0, 248, 0, 0, 252, 0, 0,
1459         256, 0, 0, 260, 0, 0, 264, 0, 0, 268, 0, 0, 272, 0, 0, 276, 0, 0, 280, 0, 0,
1460         284, 0, 0, 288, 0, 0, 292, 0, 0, 296, 0, 0, 300, 0, 0, 304, 0, 0, 308, 0, 0,
1461         312, 0, 0, 316, 0, 0, 320, 0, 0, 324, 0, 0, 328, 0, 0, 332, 0, 0, 336, 0, 0,
1462         340, 0, 0, 
1463         344,
1464     };
1465 
1466     static const int s_length_extra[] = { 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,    0,0 };
1467     static const int s_length_range[] = { 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,    0,0 };
1468 
1469 #define TOOLS_FPNG_ENSURE_32BITS() do { \
1470     if (bit_buf_size < 32) { \
1471         if ((src_ofs + 4) > src_len) return false; \
1472         bit_buf |= ((uint64_t)READ_LE32(pSrc + src_ofs)) << bit_buf_size; \
1473         src_ofs += 4; bit_buf_size += 32; } \
1474     } while(0)
1475 
1476 #define TOOLS_FPNG_GET_BITS(b, ll) do { \
1477     uint32_t l = ll; assert(l && (l <= 32)); \
1478     b = (uint32_t)(bit_buf & g_bitmasks[l]); \
1479     bit_buf >>= l; \
1480     bit_buf_size -= l; \
1481     TOOLS_FPNG_ENSURE_32BITS(); \
1482     } while(0)
1483 
1484 #define TOOLS_FPNG_SKIP_BITS(ll) do { \
1485     uint32_t l = ll; assert(l <= 32); \
1486     bit_buf >>= l; \
1487     bit_buf_size -= l; \
1488     TOOLS_FPNG_ENSURE_32BITS(); \
1489     } while(0)
1490 
1491 #define TOOLS_FPNG_GET_BITS_NE(b, ll) do { \
1492     uint32_t l = ll; assert(l && (l <= 32) && (bit_buf_size >= l)); \
1493     b = (uint32_t)(bit_buf & g_bitmasks[l]); \
1494     bit_buf >>= l; \
1495     bit_buf_size -= l; \
1496     } while(0)
1497 
1498 #define TOOLS_FPNG_SKIP_BITS_NE(ll) do { \
1499     uint32_t l = ll; assert(l <= 32 && (bit_buf_size >= l)); \
1500     bit_buf >>= l; \
1501     bit_buf_size -= l; \
1502     } while(0)
1503 
1504     static bool prepare_dynamic_block(
1505         const uint8_t* pSrc, uint32_t src_len, uint32_t& src_ofs,
1506         uint32_t& bit_buf_size, uint64_t& bit_buf,
1507         uint32_t* pLit_table, uint32_t num_chans)
1508     {
1509         static const uint8_t s_bit_length_order[] = { 16, 17, 18, 0, 8,  7,  9, 6, 10,  5, 11, 4, 12,  3, 13, 2, 14,  1, 15 };
1510 
1511         uint32_t num_lit_codes, num_dist_codes, num_clen_codes;
1512 
1513         TOOLS_FPNG_GET_BITS(num_lit_codes, 5);
1514         num_lit_codes += 257;
1515 
1516         TOOLS_FPNG_GET_BITS(num_dist_codes, 5);
1517         num_dist_codes += 1;
1518         
1519         uint32_t total_codes = num_lit_codes + num_dist_codes;
1520         if (total_codes > (DEFL_MAX_HUFF_SYMBOLS_0 + DEFL_MAX_HUFF_SYMBOLS_1))
1521             return false;
1522 
1523         uint8_t code_sizes[DEFL_MAX_HUFF_SYMBOLS_0 + DEFL_MAX_HUFF_SYMBOLS_1];
1524         memset(code_sizes, 0, sizeof(code_sizes));
1525 
1526         TOOLS_FPNG_GET_BITS(num_clen_codes, 4);
1527         num_clen_codes += 4;
1528 
1529         uint8_t clen_codesizes[DEFL_MAX_HUFF_SYMBOLS_2];
1530         memset(clen_codesizes, 0, sizeof(clen_codesizes));
1531 
1532         for (uint32_t i = 0; i < num_clen_codes; i++)
1533         {
1534             uint32_t len = 0;
1535             TOOLS_FPNG_GET_BITS(len, 3);
1536             clen_codesizes[s_bit_length_order[i]] = (uint8_t)len;
1537         }
1538 
1539         uint32_t clen_table[FPNG_DECODER_TABLE_SIZE];
1540         if (!build_decoder_table(DEFL_MAX_HUFF_SYMBOLS_2, clen_codesizes, clen_table))
1541             return false;
1542 
1543         uint32_t min_code_size = 15;
1544 
1545         for (uint32_t cur_code = 0; cur_code < total_codes; )
1546         {
1547             uint32_t sym = clen_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1548             uint32_t sym_len = sym >> 9;
1549             if (!sym_len)
1550                 return false;
1551             TOOLS_FPNG_SKIP_BITS(sym_len);
1552             sym &= 511;
1553                         
1554             if (sym <= 15)
1555             {
1556                 // Can't be a fpng Huffman table
1557                 if (sym > FPNG_DECODER_TABLE_BITS)
1558                     return false;
1559 
1560                 if (sym)
1561                     min_code_size = minimum(min_code_size, sym);
1562 
1563                 code_sizes[cur_code++] = (uint8_t)sym;
1564                 continue;
1565             }
1566 
1567             uint32_t rep_len = 0, rep_code_size = 0;
1568 
1569             switch (sym)
1570             {
1571             case 16:
1572             {
1573                 TOOLS_FPNG_GET_BITS(rep_len, 2);
1574                 rep_len += 3;
1575                 if (!cur_code)
1576                     return false;
1577                 rep_code_size = code_sizes[cur_code - 1];
1578                 break;
1579             }
1580             case 17:
1581             {
1582                 TOOLS_FPNG_GET_BITS(rep_len, 3);
1583                 rep_len += 3;
1584                 rep_code_size = 0;
1585                 break;
1586             }
1587             case 18:
1588             {
1589                 TOOLS_FPNG_GET_BITS(rep_len, 7);
1590                 rep_len += 11;
1591                 rep_code_size = 0;
1592                 break;
1593             }
1594             }
1595 
1596             if ((cur_code + rep_len) > total_codes)
1597                 return false;
1598 
1599             for (; rep_len; rep_len--)
1600                 code_sizes[cur_code++] = (uint8_t)rep_code_size;
1601         }
1602 
1603         uint8_t lit_codesizes[DEFL_MAX_HUFF_SYMBOLS_0];
1604 
1605         memcpy(lit_codesizes, code_sizes, num_lit_codes);
1606         memset(lit_codesizes + num_lit_codes, 0, DEFL_MAX_HUFF_SYMBOLS_0 - num_lit_codes);
1607 
1608         uint32_t total_valid_distcodes = 0;
1609         for (uint32_t i = 0; i < num_dist_codes; i++)
1610             total_valid_distcodes += (code_sizes[num_lit_codes + i] == 1);
1611         
1612         // 1 or 2 because the first version of FPNG only issued 1 valid distance code, but that upset wuffs. So we let 1 or 2 through.
1613         if ((total_valid_distcodes < 1) || (total_valid_distcodes > 2))
1614             return false;
1615 
1616         if (code_sizes[num_lit_codes + (num_chans - 1)] != 1)
1617             return false;
1618 
1619         if (total_valid_distcodes == 2)
1620         {
1621             // If there are two valid distance codes, make sure the first is 1 bit.
1622             if (code_sizes[num_lit_codes + num_chans] != 1)
1623                 return false;
1624         }
1625                         
1626         if (!build_decoder_table(num_lit_codes, lit_codesizes, pLit_table))
1627             return false;
1628 
1629         // Add next symbol to decoder table, when it fits
1630         for (uint32_t i = 0; i < FPNG_DECODER_TABLE_SIZE; i++)
1631         {
1632             uint32_t sym = pLit_table[i] & 511;
1633             if (sym >= 256)
1634                 continue;
1635 
1636             uint32_t sym_bits = (pLit_table[i] >> 9) & 15;
1637             if (!sym_bits)
1638                 continue;
1639             assert(sym_bits <= FPNG_DECODER_TABLE_BITS);
1640 
1641             uint32_t bits_left = FPNG_DECODER_TABLE_BITS - sym_bits;
1642             if (bits_left < min_code_size)
1643                 continue;
1644 
1645             uint32_t next_bits = i >> sym_bits;
1646             uint32_t next_sym = pLit_table[next_bits] & 511;
1647             uint32_t next_sym_bits = (pLit_table[next_bits] >> 9) & 15;
1648             if ((!next_sym_bits) || (bits_left < next_sym_bits))
1649                 continue;
1650 
1651             pLit_table[i] |= (next_sym << 16) | (next_sym_bits << (16 + 9));
1652         }
1653 
1654         return true;
1655     }
1656         
1657     static bool fpng_pixel_zlib_raw_decompress(
1658         const uint8_t* pSrc, uint32_t src_len, uint32_t zlib_len,
1659         uint8_t* pDst, uint32_t w, uint32_t h,
1660         uint32_t src_chans, uint32_t dst_chans)
1661     {
1662         assert((src_chans == 3) || (src_chans == 4));
1663         assert((dst_chans == 3) || (dst_chans == 4));
1664         
1665         const uint32_t src_bpl = w * src_chans;
1666         const uint32_t dst_bpl = w * dst_chans;
1667         const uint32_t dst_len = dst_bpl * h;
1668 
1669         uint32_t src_ofs = 2;
1670         uint32_t dst_ofs = 0;
1671         uint32_t raster_ofs = 0;
1672         uint32_t comp_ofs = 0;
1673 
1674         for (; ; )
1675         {
1676             if ((src_ofs + 1) > src_len)
1677                 return false;
1678 
1679             const bool bfinal = (pSrc[src_ofs] & 1) != 0;
1680             const uint32_t btype = (pSrc[src_ofs] >> 1) & 3;
1681             if (btype != 0)
1682                 return false;
1683 
1684             src_ofs++;
1685 
1686             if ((src_ofs + 4) > src_len)
1687                 return false;
1688             uint32_t len = pSrc[src_ofs + 0] | (pSrc[src_ofs + 1] << 8);
1689             uint32_t nlen = pSrc[src_ofs + 2] | (pSrc[src_ofs + 3] << 8);
1690             src_ofs += 4;
1691 
1692             if (len != (~nlen & 0xFFFF))
1693                 return false;
1694 
1695             if ((src_ofs + len) > src_len)
1696                 return false;
1697 
1698             // Raw blocks are a relatively uncommon case so this isn't well optimized.
1699             // Supports 3->4 and 4->3 byte/pixel conversion.
1700             for (uint32_t i = 0; i < len; i++)
1701             {
1702                 uint32_t c = pSrc[src_ofs + i];
1703 
1704                 if (!raster_ofs)
1705                 {
1706                     // Check filter type
1707                     if (c != 0)
1708                         return false;
1709                     
1710                     assert(!comp_ofs);
1711                 }
1712                 else
1713                 {
1714                     if (comp_ofs < dst_chans)
1715                     {
1716                         if (dst_ofs == dst_len)
1717                             return false;
1718 
1719                         pDst[dst_ofs++] = (uint8_t)c;
1720                     }
1721                     
1722                     if (++comp_ofs == src_chans)
1723                     {
1724                         if (dst_chans > src_chans)
1725                         {
1726                             if (dst_ofs == dst_len)
1727                                 return false;
1728 
1729                             pDst[dst_ofs++] = (uint8_t)0xFF;
1730                         }
1731 
1732                         comp_ofs = 0;
1733                     }
1734                 }
1735 
1736                 if (++raster_ofs == (src_bpl + 1))
1737                 {
1738                     assert(!comp_ofs);
1739                     raster_ofs = 0;
1740                 }
1741             }
1742 
1743             src_ofs += len;
1744 
1745             if (bfinal)
1746                 break;
1747         }
1748 
1749         if (comp_ofs != 0)
1750             return false;
1751 
1752         // Check for zlib adler32
1753         if ((src_ofs + 4) != zlib_len)
1754             return false;
1755 
1756         return (dst_ofs == dst_len);
1757     }
1758     
1759     template<uint32_t dst_comps>
1760     static bool fpng_pixel_zlib_decompress_3(
1761         const uint8_t* pSrc, uint32_t src_len, uint32_t zlib_len,
1762         uint8_t* pDst, uint32_t w, uint32_t h)
1763     {
1764         assert(src_len >= (zlib_len + 4));
1765 
1766         const uint32_t dst_bpl = w * dst_comps;
1767         //const uint32_t dst_len = dst_bpl * h;
1768 
1769         if (zlib_len < 7)
1770             return false;
1771 
1772         // check zlib header
1773         if ((pSrc[0] != 0x78) || (pSrc[1] != 0x01))
1774             return false;
1775 
1776         uint32_t src_ofs = 2;
1777         
1778         if ((pSrc[src_ofs] & 6) == 0)
1779             return fpng_pixel_zlib_raw_decompress(pSrc, src_len, zlib_len, pDst, w, h, 3, dst_comps);
1780         
1781         if ((src_ofs + 4) > src_len)
1782             return false;
1783         uint64_t bit_buf = READ_LE32(pSrc + src_ofs);
1784         src_ofs += 4;
1785 
1786         uint32_t bit_buf_size = 32;
1787 
1788         uint32_t bfinal, btype;
1789         TOOLS_FPNG_GET_BITS(bfinal, 1);
1790         TOOLS_FPNG_GET_BITS(btype, 2);
1791 
1792         // Must be the final block or it's not valid, and type=2 (dynamic)
1793         if ((bfinal != 1) || (btype != 2))
1794             return false;
1795         
1796         uint32_t lit_table[FPNG_DECODER_TABLE_SIZE];
1797         if (!prepare_dynamic_block(pSrc, src_len, src_ofs, bit_buf_size, bit_buf, lit_table, 3))
1798             return false;
1799 
1800         const uint8_t* pPrev_scanline = NULL/*nullptr*/;
1801         uint8_t* pCur_scanline = pDst;
1802 
1803         for (uint32_t y = 0; y < h; y++)
1804         {
1805             // At start of PNG scanline, so read the filter literal
1806             assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
1807             uint32_t filter = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1808             uint32_t filter_len = (filter >> 9) & 15;
1809             if (!filter_len)
1810                 return false;
1811             TOOLS_FPNG_SKIP_BITS(filter_len);
1812             filter &= 511;
1813 
1814             uint32_t expected_filter = (y ? 2 : 0);
1815             if (filter != expected_filter)
1816                 return false;
1817 
1818             uint32_t x_ofs = 0;
1819             uint8_t prev_delta_r = 0, prev_delta_g = 0, prev_delta_b = 0;
1820             do
1821             {
1822                 assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
1823                 uint32_t lit0_tab = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1824                 
1825                 uint32_t lit0 = lit0_tab;
1826                 uint32_t lit0_len = (lit0_tab >> 9) & 15;
1827                 if (!lit0_len)
1828                     return false;
1829                 TOOLS_FPNG_SKIP_BITS(lit0_len);
1830 
1831                 if (lit0 & 256)
1832                 {
1833                     lit0 &= 511;
1834 
1835                     // Can't be EOB - we still have more pixels to decompress.
1836                     if (lit0 == 256)
1837                         return false;
1838 
1839                     // Must be an RLE match against the previous pixel.
1840                     uint32_t run_len = s_length_range[lit0 - 257];
1841                     if (lit0 >= 265)
1842                     {
1843                         uint32_t e;
1844                         TOOLS_FPNG_GET_BITS_NE(e, s_length_extra[lit0 - 257]);
1845 
1846                         run_len += e;
1847                     }
1848                     
1849                     // Skip match distance - it's always the same (3)
1850                     TOOLS_FPNG_SKIP_BITS_NE(1);
1851 
1852                     // Matches must always be a multiple of 3/4 bytes
1853                     assert((run_len % 3) == 0);
1854                                                                                 
1855                     if (dst_comps == 4)
1856                     {
1857                         const uint32_t x_ofs_end = x_ofs + g_run_len3_to_4[run_len];
1858                         
1859                         // Check for valid run lengths
1860                         if (x_ofs == x_ofs_end)
1861                             return false;
1862 
1863                         // Matches cannot cross scanlines.
1864                         if (x_ofs_end > dst_bpl)
1865                             return false;
1866 
1867                         if (pPrev_scanline)
1868                         {
1869                             if ((prev_delta_r | prev_delta_g | prev_delta_b) == 0)
1870                             {
1871                                 memcpy(pCur_scanline + x_ofs, pPrev_scanline + x_ofs, x_ofs_end - x_ofs);
1872                                 x_ofs = x_ofs_end;
1873                             }
1874                             else
1875                             {
1876                                 do
1877                                 {
1878                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + prev_delta_r);
1879                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + prev_delta_g);
1880                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + prev_delta_b);
1881                                     pCur_scanline[x_ofs + 3] = 0xFF;
1882                                     x_ofs += 4;
1883                                 } while (x_ofs < x_ofs_end);
1884                             }
1885                         }
1886                         else
1887                         {
1888                             do
1889                             {
1890                                 pCur_scanline[x_ofs] = prev_delta_r;
1891                                 pCur_scanline[x_ofs + 1] = prev_delta_g;
1892                                 pCur_scanline[x_ofs + 2] = prev_delta_b;
1893                                 pCur_scanline[x_ofs + 3] = 0xFF;
1894                                 x_ofs += 4;
1895                             } while (x_ofs < x_ofs_end);
1896                         }
1897                     }
1898                     else
1899                     {
1900                         // Check for valid run lengths
1901                         if (!g_run_len3_to_4[run_len])
1902                             return false;
1903 
1904                         const uint32_t x_ofs_end = x_ofs + run_len;
1905 
1906                         // Matches cannot cross scanlines.
1907                         if (x_ofs_end > dst_bpl)
1908                             return false;
1909 
1910                         if (pPrev_scanline)
1911                         {
1912                             if ((prev_delta_r | prev_delta_g | prev_delta_b) == 0)
1913                             {
1914                                 memcpy(pCur_scanline + x_ofs, pPrev_scanline + x_ofs, run_len);
1915                                 x_ofs = x_ofs_end;
1916                             }
1917                             else
1918                             {
1919                                 do
1920                                 {
1921                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + prev_delta_r);
1922                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + prev_delta_g);
1923                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + prev_delta_b);
1924                                     x_ofs += 3;
1925                                 } while (x_ofs < x_ofs_end);
1926                             }
1927                         }
1928                         else
1929                         {
1930                             do
1931                             {
1932                                 pCur_scanline[x_ofs] = prev_delta_r;
1933                                 pCur_scanline[x_ofs + 1] = prev_delta_g;
1934                                 pCur_scanline[x_ofs + 2] = prev_delta_b;
1935                                 x_ofs += 3;
1936                             } while (x_ofs < x_ofs_end);
1937                         }
1938                     }
1939                 }
1940                 else
1941                 {
1942                     uint32_t lit1, lit2;
1943 
1944                     uint32_t lit1_spec_len = (lit0_tab >> (16 + 9));
1945                     uint32_t lit2_len;
1946                     if (lit1_spec_len)
1947                     {
1948                         lit1 = (lit0_tab >> 16) & 511;
1949                         TOOLS_FPNG_SKIP_BITS_NE(lit1_spec_len);
1950 
1951                         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
1952                         lit2 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1953                         lit2_len = (lit2 >> 9) & 15;
1954                         if (!lit2_len)
1955                             return false;
1956                     }
1957                     else
1958                     {
1959                         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
1960                         lit1 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1961                         uint32_t lit1_len = (lit1 >> 9) & 15;
1962                         if (!lit1_len)
1963                             return false;
1964                         TOOLS_FPNG_SKIP_BITS_NE(lit1_len);
1965 
1966                         lit2_len = (lit1 >> (16 + 9));
1967                         if (lit2_len)
1968                             lit2 = lit1 >> 16;
1969                         else
1970                         {
1971                             assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
1972                             lit2 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
1973                             lit2_len = (lit2 >> 9) & 15;
1974                             if (!lit2_len)
1975                                 return false;
1976                         }
1977                     }
1978 
1979                     TOOLS_FPNG_SKIP_BITS(lit2_len);
1980                     
1981                     // Check for matches
1982                     if ((lit1 | lit2) & 256)
1983                         return false;
1984 
1985                     if (dst_comps == 4)
1986                     {
1987                         if (pPrev_scanline)
1988                         {
1989                             pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
1990                             pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
1991                             pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
1992                             pCur_scanline[x_ofs + 3] = 0xFF;
1993                         }
1994                         else
1995                         {
1996                             pCur_scanline[x_ofs] = (uint8_t)lit0;
1997                             pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
1998                             pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
1999                             pCur_scanline[x_ofs + 3] = 0xFF;
2000                         }
2001                         x_ofs += 4;
2002                     }
2003                     else
2004                     {
2005                         if (pPrev_scanline)
2006                         {
2007                             pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
2008                             pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
2009                             pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
2010                         }
2011                         else
2012                         {
2013                             pCur_scanline[x_ofs] = (uint8_t)lit0;
2014                             pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
2015                             pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
2016                         }
2017                         x_ofs += 3;
2018                     }
2019 
2020                     prev_delta_r = (uint8_t)lit0;
2021                     prev_delta_g = (uint8_t)lit1;
2022                     prev_delta_b = (uint8_t)lit2;
2023                                         
2024                     // See if we can decode one more pixel.
2025                     uint32_t spec_next_len0_len = lit2 >> (16 + 9);
2026                     if ((spec_next_len0_len) && (x_ofs < dst_bpl))
2027                     {
2028                         lit0 = (lit2 >> 16) & 511;
2029                         if (lit0 < 256)
2030                         {
2031                             TOOLS_FPNG_SKIP_BITS_NE(spec_next_len0_len);
2032 
2033                             assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2034                             lit1 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2035                             uint32_t lit1_len = (lit1 >> 9) & 15;
2036                             if (!lit1_len)
2037                                 return false;
2038                             TOOLS_FPNG_SKIP_BITS(lit1_len);
2039 
2040                             lit2_len = (lit1 >> (16 + 9));
2041                             if (lit2_len)
2042                                 lit2 = lit1 >> 16;
2043                             else
2044                             {
2045                                 assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2046                                 lit2 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2047                                 lit2_len = (lit2 >> 9) & 15;
2048                                 if (!lit2_len)
2049                                     return false;
2050                             }
2051 
2052                             TOOLS_FPNG_SKIP_BITS_NE(lit2_len);
2053 
2054                             // Check for matches
2055                             if ((lit1 | lit2) & 256)
2056                                 return false;
2057                     
2058                             if (dst_comps == 4)
2059                             {
2060                                 if (pPrev_scanline)
2061                                 {
2062                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
2063                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
2064                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
2065                                     pCur_scanline[x_ofs + 3] = 0xFF;
2066                                 }
2067                                 else
2068                                 {
2069                                     pCur_scanline[x_ofs] = (uint8_t)lit0;
2070                                     pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
2071                                     pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
2072                                     pCur_scanline[x_ofs + 3] = 0xFF;
2073                                 }
2074                                 x_ofs += 4;
2075                             }
2076                             else
2077                             {
2078                                 if (pPrev_scanline)
2079                                 {
2080                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
2081                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
2082                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
2083                                 }
2084                                 else
2085                                 {
2086                                     pCur_scanline[x_ofs] = (uint8_t)lit0;
2087                                     pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
2088                                     pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
2089                                 }
2090                                 x_ofs += 3;
2091                             }
2092 
2093                             prev_delta_r = (uint8_t)lit0;
2094                             prev_delta_g = (uint8_t)lit1;
2095                             prev_delta_b = (uint8_t)lit2;
2096                                                                                 
2097                         } // if (lit0 < 256)
2098 
2099                     } // if ((spec_next_len0_len) && (x_ofs < bpl))
2100                 }
2101 
2102             } while (x_ofs < dst_bpl);
2103 
2104             pPrev_scanline = pCur_scanline;
2105             pCur_scanline += dst_bpl;
2106 
2107         } // y
2108 
2109         // The last symbol should be EOB
2110         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2111         uint32_t lit0 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2112         uint32_t lit0_len = (lit0 >> 9) & 15;
2113         if (!lit0_len)
2114             return false;
2115         lit0 &= 511;
2116         if (lit0 != 256)
2117             return false;
2118 
2119         bit_buf_size -= lit0_len;
2120         bit_buf >>= lit0_len;
2121 
2122         uint32_t align_bits = bit_buf_size & 7;
2123         bit_buf_size -= align_bits;
2124         bit_buf >>= align_bits;
2125 
2126         if (src_ofs < (bit_buf_size >> 3))
2127             return false;
2128         src_ofs -= (bit_buf_size >> 3);
2129 
2130         // We should be at the very end, because the bit buf reads ahead 32-bits (which contains the zlib adler32).
2131         if ((src_ofs + 4) != zlib_len)
2132             return false;
2133 
2134         return true;
2135     }
2136 
2137     template<uint32_t dst_comps>
2138     static bool fpng_pixel_zlib_decompress_4(
2139         const uint8_t* pSrc, uint32_t src_len, uint32_t zlib_len,
2140         uint8_t* pDst, uint32_t w, uint32_t h)
2141     {
2142         assert(src_len >= (zlib_len + 4));
2143 
2144         const uint32_t dst_bpl = w * dst_comps;
2145         //const uint32_t dst_len = dst_bpl * h;
2146 
2147         if (zlib_len < 7)
2148             return false;
2149 
2150         // check zlib header
2151         if ((pSrc[0] != 0x78) || (pSrc[1] != 0x01))
2152             return false;
2153 
2154         uint32_t src_ofs = 2;
2155 
2156         if ((pSrc[src_ofs] & 6) == 0)
2157             return fpng_pixel_zlib_raw_decompress(pSrc, src_len, zlib_len, pDst, w, h, 4, dst_comps);
2158 
2159         if ((src_ofs + 4) > src_len)
2160             return false;
2161         uint64_t bit_buf = READ_LE32(pSrc + src_ofs);
2162         src_ofs += 4;
2163 
2164         uint32_t bit_buf_size = 32;
2165 
2166         uint32_t bfinal, btype;
2167         TOOLS_FPNG_GET_BITS(bfinal, 1);
2168         TOOLS_FPNG_GET_BITS(btype, 2);
2169 
2170         // Must be the final block or it's not valid, and type=2 (dynamic)
2171         if ((bfinal != 1) || (btype != 2))
2172             return false;
2173 
2174         uint32_t lit_table[FPNG_DECODER_TABLE_SIZE];
2175         if (!prepare_dynamic_block(pSrc, src_len, src_ofs, bit_buf_size, bit_buf, lit_table, 4))
2176             return false;
2177 
2178         const uint8_t* pPrev_scanline = NULL/*nullptr*/;
2179         uint8_t* pCur_scanline = pDst;
2180 
2181         for (uint32_t y = 0; y < h; y++)
2182         {
2183             // At start of PNG scanline, so read the filter literal
2184             assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2185             uint32_t filter = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2186             uint32_t filter_len = (filter >> 9) & 15;
2187             if (!filter_len)
2188                 return false;
2189             TOOLS_FPNG_SKIP_BITS(filter_len);
2190             filter &= 511;
2191 
2192             uint32_t expected_filter = (y ? 2 : 0);
2193             if (filter != expected_filter)
2194                 return false;
2195 
2196             uint32_t x_ofs = 0;
2197             uint8_t prev_delta_r = 0, prev_delta_g = 0, prev_delta_b = 0, prev_delta_a = 0;
2198             do
2199             {
2200                 assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2201                 uint32_t lit0_tab = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2202 
2203                 uint32_t lit0 = lit0_tab;
2204                 uint32_t lit0_len = (lit0_tab >> 9) & 15;
2205                 if (!lit0_len)
2206                     return false;
2207                 TOOLS_FPNG_SKIP_BITS(lit0_len);
2208 
2209                 if (lit0 & 256)
2210                 {
2211                     lit0 &= 511;
2212 
2213                     // Can't be EOB - we still have more pixels to decompress.
2214                     if (lit0 == 256)
2215                         return false;
2216 
2217                     // Must be an RLE match against the previous pixel.
2218                     uint32_t run_len = s_length_range[lit0 - 257];
2219                     if (lit0 >= 265)
2220                     {
2221                         uint32_t e;
2222                         TOOLS_FPNG_GET_BITS_NE(e, s_length_extra[lit0 - 257]);
2223 
2224                         run_len += e;
2225                     }
2226 
2227                     // Skip match distance - it's always the same (4)
2228                     TOOLS_FPNG_SKIP_BITS_NE(1);
2229 
2230                     // Matches must always be a multiple of 3/4 bytes
2231                     if (run_len & 3)
2232                         return false;
2233                                         
2234                     if (dst_comps == 3)
2235                     {
2236                         const uint32_t run_len3 = (run_len >> 2) * 3;
2237                         const uint32_t x_ofs_end = x_ofs + run_len3;
2238 
2239                         // Matches cannot cross scanlines.
2240                         if (x_ofs_end > dst_bpl)
2241                             return false;
2242 
2243                         if (pPrev_scanline)
2244                         {
2245                             if ((prev_delta_r | prev_delta_g | prev_delta_b | prev_delta_a) == 0)
2246                             {
2247                                 memcpy(pCur_scanline + x_ofs, pPrev_scanline + x_ofs, run_len3);
2248                                 x_ofs = x_ofs_end;
2249                             }
2250                             else
2251                             {
2252                                 do
2253                                 {
2254                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + prev_delta_r);
2255                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + prev_delta_g);
2256                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + prev_delta_b);
2257                                     x_ofs += 3;
2258                                 } while (x_ofs < x_ofs_end);
2259                             }
2260                         }
2261                         else
2262                         {
2263                             do
2264                             {
2265                                 pCur_scanline[x_ofs] = prev_delta_r;
2266                                 pCur_scanline[x_ofs + 1] = prev_delta_g;
2267                                 pCur_scanline[x_ofs + 2] = prev_delta_b;
2268                                 x_ofs += 3;
2269                             } while (x_ofs < x_ofs_end);
2270                         }
2271                     }
2272                     else
2273                     {
2274                         const uint32_t x_ofs_end = x_ofs + run_len;
2275 
2276                         // Matches cannot cross scanlines.
2277                         if (x_ofs_end > dst_bpl)
2278                             return false;
2279 
2280                         if (pPrev_scanline)
2281                         {
2282                             if ((prev_delta_r | prev_delta_g | prev_delta_b | prev_delta_a) == 0)
2283                             {
2284                                 memcpy(pCur_scanline + x_ofs, pPrev_scanline + x_ofs, run_len);
2285                                 x_ofs = x_ofs_end;
2286                             }
2287                             else
2288                             {
2289                                 do
2290                                 {
2291                                     pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + prev_delta_r);
2292                                     pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + prev_delta_g);
2293                                     pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + prev_delta_b);
2294                                     pCur_scanline[x_ofs + 3] = (uint8_t)(pPrev_scanline[x_ofs + 3] + prev_delta_a);
2295                                     x_ofs += 4;
2296                                 } while (x_ofs < x_ofs_end);
2297                             }
2298                         }
2299                         else
2300                         {
2301                             do
2302                             {
2303                                 pCur_scanline[x_ofs] = prev_delta_r;
2304                                 pCur_scanline[x_ofs + 1] = prev_delta_g;
2305                                 pCur_scanline[x_ofs + 2] = prev_delta_b;
2306                                 pCur_scanline[x_ofs + 3] = prev_delta_a;
2307                                 x_ofs += 4;
2308                             } while (x_ofs < x_ofs_end);
2309                         }
2310                     }
2311                 }
2312                 else
2313                 {
2314                     uint32_t lit1, lit2;
2315 
2316                     uint32_t lit1_spec_len = (lit0_tab >> (16 + 9));
2317                     uint32_t lit2_len;
2318                     if (lit1_spec_len)
2319                     {
2320                         lit1 = (lit0_tab >> 16) & 511;
2321                         TOOLS_FPNG_SKIP_BITS_NE(lit1_spec_len);
2322 
2323                         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2324                         lit2 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2325                         lit2_len = (lit2 >> 9) & 15;
2326                         if (!lit2_len)
2327                             return false;
2328                     }
2329                     else
2330                     {
2331                         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2332                         lit1 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2333                         uint32_t lit1_len = (lit1 >> 9) & 15;
2334                         if (!lit1_len)
2335                             return false;
2336                         TOOLS_FPNG_SKIP_BITS_NE(lit1_len);
2337 
2338                         lit2_len = (lit1 >> (16 + 9));
2339                         if (lit2_len)
2340                             lit2 = lit1 >> 16;
2341                         else
2342                         {
2343                             assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2344                             lit2 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2345                             lit2_len = (lit2 >> 9) & 15;
2346                             if (!lit2_len)
2347                                 return false;
2348                         }
2349                     }
2350 
2351                     uint32_t lit3;
2352                     uint32_t lit3_len = lit2 >> (16 + 9);
2353                     
2354                     if (lit3_len)
2355                     {
2356                         lit3 = (lit2 >> 16);
2357                         TOOLS_FPNG_SKIP_BITS(lit2_len + lit3_len);
2358                     }
2359                     else
2360                     {
2361                         TOOLS_FPNG_SKIP_BITS(lit2_len);
2362 
2363                         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2364                         lit3 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2365                         lit3_len = (lit3 >> 9) & 15;
2366                         if (!lit3_len)
2367                             return false;
2368 
2369                         TOOLS_FPNG_SKIP_BITS_NE(lit3_len);
2370                     }
2371                                         
2372                     // Check for matches
2373                     if ((lit1 | lit2 | lit3) & 256)
2374                         return false;
2375 
2376                     if (dst_comps == 3)
2377                     {
2378                         if (pPrev_scanline)
2379                         {
2380                             pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
2381                             pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
2382                             pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
2383                         }
2384                         else
2385                         {
2386                             pCur_scanline[x_ofs] = (uint8_t)lit0;
2387                             pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
2388                             pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
2389                         }
2390 
2391                         x_ofs += 3;
2392                     }
2393                     else
2394                     {
2395                         if (pPrev_scanline)
2396                         {
2397                             pCur_scanline[x_ofs] = (uint8_t)(pPrev_scanline[x_ofs] + lit0);
2398                             pCur_scanline[x_ofs + 1] = (uint8_t)(pPrev_scanline[x_ofs + 1] + lit1);
2399                             pCur_scanline[x_ofs + 2] = (uint8_t)(pPrev_scanline[x_ofs + 2] + lit2);
2400                             pCur_scanline[x_ofs + 3] = (uint8_t)(pPrev_scanline[x_ofs + 3] + lit3);
2401                         }
2402                         else
2403                         {
2404                             pCur_scanline[x_ofs] = (uint8_t)lit0;
2405                             pCur_scanline[x_ofs + 1] = (uint8_t)lit1;
2406                             pCur_scanline[x_ofs + 2] = (uint8_t)lit2;
2407                             pCur_scanline[x_ofs + 3] = (uint8_t)lit3;
2408                         }
2409                         
2410                         x_ofs += 4;
2411                     }
2412 
2413                     prev_delta_r = (uint8_t)lit0;
2414                     prev_delta_g = (uint8_t)lit1;
2415                     prev_delta_b = (uint8_t)lit2;
2416                     prev_delta_a = (uint8_t)lit3;
2417                 }
2418 
2419             } while (x_ofs < dst_bpl);
2420 
2421             pPrev_scanline = pCur_scanline;
2422             pCur_scanline += dst_bpl;
2423         } // y
2424 
2425         // The last symbol should be EOB
2426         assert(bit_buf_size >= FPNG_DECODER_TABLE_BITS);
2427         uint32_t lit0 = lit_table[bit_buf & (FPNG_DECODER_TABLE_SIZE - 1)];
2428         uint32_t lit0_len = (lit0 >> 9) & 15;
2429         if (!lit0_len)
2430             return false;
2431         lit0 &= 511;
2432         if (lit0 != 256)
2433             return false;
2434 
2435         bit_buf_size -= lit0_len;
2436         bit_buf >>= lit0_len;
2437 
2438         uint32_t align_bits = bit_buf_size & 7;
2439         bit_buf_size -= align_bits;
2440         bit_buf >>= align_bits;
2441 
2442         if (src_ofs < (bit_buf_size >> 3))
2443             return false;
2444         src_ofs -= (bit_buf_size >> 3);
2445 
2446         // We should be at the very end, because the bit buf reads ahead 32-bits (which contains the zlib adler32).
2447         if ((src_ofs + 4) != zlib_len)
2448             return false;
2449 
2450         return true;
2451     }
2452 
2453 #pragma pack(push)
2454 #pragma pack(1)
2455     struct png_chunk_prefix
2456     {
2457         uint32_t m_length;
2458         uint8_t m_type[4];
2459     };
2460     struct png_ihdr
2461     {
2462         png_chunk_prefix m_prefix;
2463         uint32_t m_width;
2464         uint32_t m_height;
2465         uint8_t m_bitdepth;
2466         uint8_t m_color_type;
2467         uint8_t m_comp_method;
2468         uint8_t m_filter_method;
2469         uint8_t m_interlace_method;
2470         uint32_t m_crc32;
2471     };
2472     const uint32_t IHDR_EXPECTED_LENGTH = 13;
2473     struct png_iend
2474     {
2475         png_chunk_prefix m_prefix;
2476         uint32_t m_crc32;
2477     };
2478 #pragma pack(pop)
2479 
2480     static int fpng_get_info_internal(const void* pImage, uint32_t image_size, uint32_t& width, uint32_t& height, uint32_t& channels_in_file, uint32_t &idat_ofs, uint32_t &idat_len)
2481     {
2482         static const uint8_t s_png_sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
2483 
2484         if (!endian_check())
2485         {
2486             assert(0);
2487             return false;
2488         }
2489                 
2490         width = 0;
2491         height = 0;
2492         channels_in_file = 0;
2493         idat_ofs = 0, idat_len = 0;
2494                 
2495         // Ensure the file has at least a minimum possible size
2496         if (image_size < (sizeof(s_png_sig) + sizeof(png_ihdr) + sizeof(png_chunk_prefix) + 1 + sizeof(uint32_t) + sizeof(png_iend)))
2497             return FPNG_DECODE_FAILED_NOT_PNG;
2498 
2499         if (memcmp(pImage, s_png_sig, 8) != 0)
2500             return FPNG_DECODE_FAILED_NOT_PNG;
2501 
2502         const uint8_t* pImage_u8 = static_cast<const uint8_t*>(pImage) + 8;
2503 
2504         const png_ihdr& ihdr = *reinterpret_cast<const png_ihdr*>(pImage_u8);
2505         pImage_u8 += sizeof(png_ihdr);
2506 
2507         if (READ_BE32(&ihdr.m_prefix.m_length) != IHDR_EXPECTED_LENGTH)
2508             return FPNG_DECODE_FAILED_NOT_PNG;
2509 
2510         if (fpng_crc32(ihdr.m_prefix.m_type, 4 + IHDR_EXPECTED_LENGTH, FPNG_CRC32_INIT) != READ_BE32(&ihdr.m_crc32))
2511             return FPNG_DECODE_FAILED_HEADER_CRC32;
2512 
2513         width = READ_BE32(&ihdr.m_width);
2514         height = READ_BE32(&ihdr.m_height);
2515                 
2516         if (!width || !height || (width > FPNG_MAX_SUPPORTED_DIM) || (height > FPNG_MAX_SUPPORTED_DIM))
2517             return FPNG_DECODE_FAILED_INVALID_DIMENSIONS;
2518 
2519         uint64_t total_pixels = (uint64_t)width * height;
2520         if (total_pixels > (1 << 30))
2521             return FPNG_DECODE_FAILED_INVALID_DIMENSIONS;
2522 
2523         if ((ihdr.m_comp_method) || (ihdr.m_filter_method) || (ihdr.m_interlace_method) || (ihdr.m_bitdepth != 8))
2524             return FPNG_DECODE_NOT_FPNG;
2525 
2526         if (ihdr.m_color_type == 2)
2527             channels_in_file = 3;
2528         else if (ihdr.m_color_type == 6)
2529             channels_in_file = 4;
2530 
2531         if (!channels_in_file)
2532             return FPNG_DECODE_NOT_FPNG;
2533 
2534         // Scan all the chunks. Look for one IDAT, IEND, and our custom fdEC chunk that indicates the file was compressed by us. Skip any ancillary chunks.
2535         bool found_fdec_chunk = false;
2536         
2537         for (; ; )
2538         {
2539             const size_t src_ofs = pImage_u8 - static_cast<const uint8_t*>(pImage);
2540             if (src_ofs >= image_size)
2541                 return FPNG_DECODE_FAILED_CHUNK_PARSING;
2542 
2543             const uint32_t bytes_remaining = image_size - (uint32_t)src_ofs;
2544             if (bytes_remaining < sizeof(uint32_t) * 3)
2545                 return FPNG_DECODE_FAILED_CHUNK_PARSING;
2546 
2547             const png_chunk_prefix* pChunk = reinterpret_cast<const png_chunk_prefix*>(pImage_u8);
2548 
2549             const uint32_t chunk_len = READ_BE32(&pChunk->m_length);
2550             if ((src_ofs + sizeof(uint32_t) + chunk_len + sizeof(uint32_t)) > image_size)
2551                 return FPNG_DECODE_FAILED_CHUNK_PARSING;
2552 
2553             for (uint32_t i = 0; i < 4; i++)
2554             {
2555                 const uint8_t c = pChunk->m_type[i];
2556                 const bool is_upper = (c >= 65) && (c <= 90), is_lower = (c >= 97) && (c <= 122);
2557                 if ((!is_upper) && (!is_lower))
2558                     return FPNG_DECODE_FAILED_CHUNK_PARSING;
2559             }
2560 
2561             char chunk_type[5] = { (char)pChunk->m_type[0], (char)pChunk->m_type[1], (char)pChunk->m_type[2], (char)pChunk->m_type[3], 0 };
2562             const bool is_idat = strcmp(chunk_type, "IDAT") == 0;
2563 
2564             const uint8_t* pChunk_data = pImage_u8 + sizeof(uint32_t) * 2;
2565 
2566             if (strcmp(chunk_type, "IEND") == 0)
2567                 break;
2568             else if (is_idat)
2569             {
2570                 // If there were multiple IDAT's, or we didn't find the fdEC chunk, then it's not FPNG.
2571                 if ((idat_ofs) || (!found_fdec_chunk))
2572                     return FPNG_DECODE_NOT_FPNG;
2573 
2574                 idat_ofs = (uint32_t)src_ofs;
2575                 idat_len = chunk_len;
2576 
2577                 // Sanity check the IDAT chunk length
2578                 if (idat_len < 7)
2579                     return FPNG_DECODE_FAILED_INVALID_IDAT;
2580             }
2581             else if (strcmp(chunk_type, "fdEC") == 0)
2582             {
2583                 if (found_fdec_chunk)
2584                     return FPNG_DECODE_NOT_FPNG;
2585 
2586                 // We've got our fdEC chunk. Now make sure it's big enough and check its contents.
2587                 if (chunk_len != 5)
2588                     return FPNG_DECODE_NOT_FPNG;
2589 
2590                 // Check fdEC chunk sig
2591                 if ((pChunk_data[0] != 82) || (pChunk_data[1] != 36) || (pChunk_data[2] != 147) || (pChunk_data[3] != 227))
2592                     return FPNG_DECODE_NOT_FPNG;
2593 
2594                 // Check fdEC version
2595                 if (pChunk_data[4] != FPNG_FDEC_VERSION)
2596                     return FPNG_DECODE_NOT_FPNG;
2597 
2598                 found_fdec_chunk = true;
2599             }
2600             else
2601             {
2602                 // Bail if it's a critical chunk - can't be FPNG
2603                 if ((chunk_type[0] & 32) == 0)
2604                     return FPNG_DECODE_NOT_FPNG;
2605 
2606                 // ancillary chunk - skip it
2607             }
2608 
2609             pImage_u8 += sizeof(png_chunk_prefix) + chunk_len + sizeof(uint32_t);
2610         }
2611 
2612         if ((!found_fdec_chunk) || (!idat_ofs))
2613             return FPNG_DECODE_NOT_FPNG;
2614         
2615         return FPNG_DECODE_SUCCESS;
2616     }
2617 
2618     inline int fpng_get_info(const void* pImage, uint32_t image_size, uint32_t& width, uint32_t& height, uint32_t& channels_in_file)
2619     {
2620         uint32_t idat_ofs = 0, idat_len = 0;
2621         return fpng_get_info_internal(pImage, image_size, width, height, channels_in_file, idat_ofs, idat_len);
2622     }
2623 
2624     inline int fpng_decode_memory(const void *pImage, uint32_t image_size, std::vector<uint8_t> &out, uint32_t& width, uint32_t& height, uint32_t &channels_in_file, uint32_t desired_channels)
2625     {
2626         out.resize(0);
2627         width = 0;
2628         height = 0;
2629         channels_in_file = 0;
2630 
2631         if ((!pImage) || (!image_size) || ((desired_channels != 3) && (desired_channels != 4)))
2632         {
2633             assert(0);
2634             return FPNG_DECODE_INVALID_ARG;
2635         }
2636 
2637         uint32_t idat_ofs = 0, idat_len = 0;
2638         int status = fpng_get_info_internal(pImage, image_size, width, height, channels_in_file, idat_ofs, idat_len);
2639         if (status)
2640             return status;
2641                 
2642         const uint64_t mem_needed = (uint64_t)width * height * desired_channels;
2643         if (mem_needed > UINT32_MAX)
2644             return FPNG_DECODE_FAILED_DIMENSIONS_TOO_LARGE;
2645 
2646         // On 32-bit systems do a quick sanity check before we try to resize the output buffer.
2647         if ((sizeof(size_t) == sizeof(uint32_t)) && (mem_needed >= 0x80000000))
2648             return FPNG_DECODE_FAILED_DIMENSIONS_TOO_LARGE;
2649 
2650         out.resize(mem_needed);
2651         
2652         const uint8_t* pIDAT_data = static_cast<const uint8_t*>(pImage) + idat_ofs + sizeof(uint32_t) * 2;
2653         const uint32_t src_len = image_size - (idat_ofs + sizeof(uint32_t) * 2);
2654 
2655         bool decomp_status;
2656         if (desired_channels == 3)
2657         {
2658             if (channels_in_file == 3)
2659                 decomp_status = fpng_pixel_zlib_decompress_3<3>(pIDAT_data, src_len, idat_len, out.data(), width, height);
2660             else
2661                 decomp_status = fpng_pixel_zlib_decompress_4<3>(pIDAT_data, src_len, idat_len, out.data(), width, height);
2662         }
2663         else
2664         {
2665             if (channels_in_file == 3)
2666                 decomp_status = fpng_pixel_zlib_decompress_3<4>(pIDAT_data, src_len, idat_len, out.data(), width, height);
2667             else
2668                 decomp_status = fpng_pixel_zlib_decompress_4<4>(pIDAT_data, src_len, idat_len, out.data(), width, height);
2669         }
2670         if (!decomp_status)
2671         {
2672             // Something went wrong. Either the file data was corrupted, or it doesn't conform to one of our zlib/Deflate constraints.
2673             // The conservative thing to do is indicate it wasn't written by us, and let the general purpose PNG decoder handle it.
2674             return FPNG_DECODE_NOT_FPNG;
2675         }
2676 
2677         return FPNG_DECODE_SUCCESS;
2678     }
2679 
2680     inline int fpng_decode_file(const char* pFilename, std::vector<uint8_t>& out, uint32_t& width, uint32_t& height, uint32_t& channels_in_file, uint32_t desired_channels)
2681     {
2682                 FILE* pFile = fopen(pFilename, "rb");
2683                 if (!pFile) return FPNG_DECODE_FILE_OPEN_FAILED;
2684 
2685         if (fseek(pFile, 0, SEEK_END) != 0)
2686         {
2687             fclose(pFile);
2688             return FPNG_DECODE_FILE_SEEK_FAILED;
2689         }
2690 
2691 #ifdef _MSC_VER
2692         int64_t filesize = _ftelli64(pFile);
2693 #else
2694         int64_t filesize = ftello(pFile);
2695 #endif
2696 
2697         if (fseek(pFile, 0, SEEK_SET) != 0)
2698         {
2699             fclose(pFile);
2700             return FPNG_DECODE_FILE_SEEK_FAILED;
2701         }
2702 
2703         if ( (filesize < 0) || (filesize > UINT32_MAX) || ( (sizeof(size_t) == sizeof(uint32_t)) && (filesize > 0x70000000) ) )
2704         {
2705             fclose(pFile);
2706             return FPNG_DECODE_FILE_TOO_LARGE;
2707         }
2708 
2709         std::vector<uint8_t> buf((size_t)filesize);
2710         if (fread(buf.data(), 1, buf.size(), pFile) != buf.size())
2711         {
2712             fclose(pFile);
2713             return FPNG_DECODE_FILE_READ_FAILED;
2714         }
2715 
2716         fclose(pFile);
2717 
2718         return fpng_decode_memory(buf.data(), (uint32_t)buf.size(), out, width, height, channels_in_file, desired_channels);
2719     }
2720 
2721 #undef TOOLS_FPNG_PUT_BITS
2722 #undef TOOLS_FPNG_PUT_BITS_CZ
2723 #undef TOOLS_FPNG_PUT_BITS_FLUSH
2724 #undef TOOLS_FPNG_PUT_BITS_FORCE_FLUSH
2725 #undef TOOLS_FPNG_DEFL_CLEAR_OBJ
2726 #undef TOOLS_FPNG_DEFL_RLE_PREV_CODE_SIZE
2727 #undef TOOLS_FPNG_DEFL_RLE_ZERO_CODE_SIZE
2728 #undef TOOLS_FPNG_DEFL_DYN_PUT_BITS
2729 #undef TOOLS_FPNG_ENSURE_32BITS
2730 #undef TOOLS_FPNG_GET_BITS
2731 #undef TOOLS_FPNG_SKIP_BITS
2732 #undef TOOLS_FPNG_GET_BITS_NE
2733 #undef TOOLS_FPNG_SKIP_BITS_NE
2734 
2735 } // namespace fpng
2736 } // namespace tools
2737 
2738 /*
2739     This is free and unencumbered software released into the public domain.
2740 
2741     Anyone is free to copy, modify, publish, use, compile, sell, or
2742     distribute this software, either in source code form or as a compiled
2743     binary, for any purpose, commercial or non-commercial, and by any
2744     means.
2745 
2746     In jurisdictions that recognize copyright laws, the author or authors
2747     of this software dedicate any and all copyright interest in the
2748     software to the public domain. We make this dedication for the benefit
2749     of the public at large and to the detriment of our heirs and
2750     successors. We intend this dedication to be an overt act of
2751     relinquishment in perpetuity of all present and future rights to this
2752     software under copyright law.
2753 
2754     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2755     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2756     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2757     IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2758     OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2759     ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2760     OTHER DEALINGS IN THE SOFTWARE.
2761 
2762     For more information, please refer to <http://unlicense.org/>
2763 
2764     Richard Geldreich, Jr.
2765     12/30/2021
2766 */