rpng.h 138 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556
  1. /**********************************************************************************************
  2. *
  3. * rpng v1.5 - A simple and easy-to-use library to manage png chunks
  4. *
  5. * FEATURES:
  6. * - Load/Save images from/to raw image data
  7. * - Load/Save indexed image data (providing palette)
  8. * - Count/read/write/remove png chunks
  9. * - Operate on file or memory buffer
  10. * - Chunks data abstraction
  11. * - Add custom chunks
  12. *
  13. * LIMITATIONS:
  14. * - Bit depths of 1/2/4 bits per pixel not supported, only 8/16 bits
  15. *
  16. * POSSIBLE IMPROVEMENTS:
  17. * - Support APNG chunks, added to PNG specs recently (draft)
  18. *
  19. * CONFIGURATION:
  20. * #define RPNG_IMPLEMENTATION
  21. * Generates the implementation of the library into the included file.
  22. * If not defined, the library is in header only mode and can be included in other headers
  23. * or source files without problems. But only ONE file should hold the implementation.
  24. *
  25. * #define RPNG_DEFLATE_IMPLEMENTATION
  26. * Include sdefl/sinfl deflate implementation with rpng
  27. *
  28. * #define RPNG_NO_STDIO
  29. * Do not include FILE I/O API, only read/write from memory buffers
  30. *
  31. * #define RPNG_NO_STDIO_WARNING
  32. * Skips issuing a compiler warning when RPNG_NO_STDIO is defined.
  33. *
  34. * DEPENDENCIES: libc (C standard library)
  35. * stdlib.h Required for: malloc(), calloc(), free()
  36. * string.h Required for: memcmp(), memcpy()
  37. * stdio.h Required for: FILE, fopen(), fread(), fwrite(), fclose() (only if !RPNG_NO_STDIO)
  38. *
  39. * rpng includes internally a copy of sdefl and sinfl libraries by Micha Mettke (@vurtun)
  40. * sdelf and sinfl libraries are used for compression and decompression of deflate data streams
  41. * sdelf and sinfl are double licensed as MIT or Unlicense, check license at the end of this file
  42. *
  43. * SUMMARY of STANDARD CHUNKS:
  44. *
  45. * This table summarizes some properties of the standard chunk types.
  46. *
  47. * Based on official docs:
  48. * http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
  49. * http://www.libpng.org/pub/png/book/chapter11.html
  50. *
  51. * Critical chunks (must appear in this order, except PLTE is optional):
  52. *
  53. * Name Multi? Ordering constraints
  54. * -------------------------------------------
  55. * IHDR No Must be first
  56. * PLTE No Before IDAT
  57. * IDAT Yes Multiple IDATs must be consecutive
  58. * IEND No Must be last
  59. *
  60. * Ancillary chunks (need not appear in this order):
  61. *
  62. * Name Multi? Ordering constraints
  63. * --------------------------------------------
  64. * cHRM No Before PLTE and IDAT
  65. * gAMA No Before PLTE and IDAT
  66. * iCCP No Before PLTE and IDAT
  67. * sBIT No Before PLTE and IDAT
  68. * sRGB No Before PLTE and IDAT
  69. * bKGD No After PLTE; before IDAT
  70. * hIST No After PLTE; before IDAT
  71. * tRNS No After PLTE; before IDAT
  72. * pHYs No Before IDAT
  73. * sPLT Yes Before IDAT
  74. * tIME No None
  75. * iTXt Yes None
  76. * tEXt Yes None
  77. * zTXt Yes None
  78. *
  79. * Standard keywords for text chunks (iTXt, tEXt, zTXt):
  80. *
  81. * Title Short (one line) title or caption for image
  82. * Author Name of image's creator
  83. * Description Description of image (possibly long)
  84. * Copyright Copyright notice
  85. * Creation Time Time of original image creation
  86. * Software Software used to create the image
  87. * Disclaimer Legal disclaimer
  88. * Warning Warning of nature of content
  89. * Source Device used to create the image
  90. * Comment Miscellaneous comment; conversion from GIF comment
  91. *
  92. * VERSIONS HISTORY:
  93. * 1.5 (28-Aug-2024) ADDED: Support indexed data loading and saving (PLTE, tRNS)
  94. * ADDED: rpng_load_image_indexed() (+ memory version)
  95. * ADDED: rpng_save_image_indexed() (+ memory version)
  96. * ADDED: Automatic join of IDAT chunks when requested
  97. * REVIEWED: Crashes on images loading not found
  98. *
  99. * 1.1 (29-May-2023) UPDATED: sdefl and sinfl, fixed issue
  100. *
  101. * 1.0 (24-Dec-2021) ADDED: rpng_load_image()
  102. * ADDED: RPNG_LOG() macro
  103. * REVIEWED: rpng_save_image() filter process issues
  104. * RENAMED: rpng_create_image() to rpng_save_image()
  105. * UPDATED: sdefl to latest version 1.0
  106. * ADDED: sinfl library (internal copy) for data decompression
  107. *
  108. * 0.9 (10-Jun-2020) First completely functional version of the library
  109. *
  110. *
  111. * LICENSE: zlib/libpng
  112. *
  113. * Copyright (c) 2020-2024 Ramon Santamaria (@raysan5)
  114. *
  115. * This software is provided "as-is", without any express or implied warranty. In no event
  116. * will the authors be held liable for any damages arising from the use of this software.
  117. *
  118. * Permission is granted to anyone to use this software for any purpose, including commercial
  119. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  120. *
  121. * 1. The origin of this software must not be misrepresented; you must not claim that you
  122. * wrote the original software. If you use this software in a product, an acknowledgment
  123. * in the product documentation would be appreciated but is not required.
  124. *
  125. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  126. * as being the original software.
  127. *
  128. * 3. This notice may not be removed or altered from any source distribution.
  129. *
  130. **********************************************************************************************/
  131. #ifndef RPNG_H
  132. #define RPNG_H
  133. #define RPNG_VERSION "1.5"
  134. // Function specifiers in case library is build/used as a shared library (Windows)
  135. // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
  136. #if defined(_WIN32)
  137. #if defined(BUILD_LIBTYPE_SHARED)
  138. #define RPNGAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
  139. #elif defined(USE_LIBTYPE_SHARED)
  140. #define RPNGAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
  141. #endif
  142. #endif
  143. // Function specifiers definition
  144. #ifndef RPNGAPI
  145. #define RPNGAPI // Functions defined as 'extern' by default (implicit specifiers)
  146. #endif
  147. //----------------------------------------------------------------------------------
  148. // Defines and Macros
  149. //----------------------------------------------------------------------------------
  150. // Allow custom memory allocators
  151. #ifndef RPNG_MALLOC
  152. #define RPNG_MALLOC(sz) malloc(sz)
  153. #endif
  154. #ifndef RPNG_CALLOC
  155. #define RPNG_CALLOC(n,sz) calloc(n,sz)
  156. #endif
  157. #ifndef RPNG_REALLOC
  158. #define RPNG_REALLOC(ptr,sz) realloc(ptr,sz)
  159. #endif
  160. #ifndef RPNG_FREE
  161. #define RPNG_FREE(ptr) free(ptr)
  162. #endif
  163. // Simple log system to avoid RPNG_LOG() calls if required
  164. // NOTE: Avoiding those calls, also avoids const strings memory usage
  165. //#define RPNG_SHOW_LOG_INFO
  166. #if defined(RPNG_SHOW_LOG_INFO)
  167. #define RPNG_LOG(...) printf(__VA_ARGS__)
  168. #else
  169. #define RPNG_LOG(...)
  170. #endif
  171. #ifndef RPNG_MAX_CHUNKS_COUNT
  172. // Maximum number of chunks to read
  173. #define RPNG_MAX_CHUNKS_COUNT 64
  174. #endif
  175. #ifndef RPNG_MAX_OUTPUT_SIZE
  176. // Maximum size for temporal buffer on write/remove chunks,
  177. // buffer is scaled to required output file size before being returned
  178. #define RPNG_MAX_OUTPUT_SIZE (64*1024*1024)
  179. #endif
  180. #ifndef RPNG_COMPRESSION_LEVEL
  181. // Deflate compression level
  182. // NOTE: Default to same as stbiw: 8
  183. #define RPNG_COMPRESSION_LEVEL 8
  184. #endif
  185. // Define some possible error values
  186. // NOTE: Only some are actually used on file saving
  187. #define RPNG_SUCCESS 0 // Image saved successfully
  188. #define RPNG_ERROR_FILE_OPEN 1 // The requested file can not be opened
  189. #define RPNG_ERROR_PIXEL_FORMAT 2 // Not a supported PNG image format
  190. #define RPNG_ERROR_MEMORY_ALLOC 3 // Memory could not be allocated for operation
  191. //----------------------------------------------------------------------------------
  192. // Types and Structures Definition
  193. //----------------------------------------------------------------------------------
  194. #ifndef __cplusplus
  195. #include <stdbool.h> // Boolean type
  196. #endif
  197. // PNG chunk type
  198. typedef struct {
  199. int length; // Data length, must be converted to big endian when saving!
  200. char type[4]; // Chunk type FOURCC: IDHR, PLTE, IDAT, IEND / gAMA, sRGB, tEXt, tIME...
  201. char *data; // Chunk data pointer
  202. unsigned int crc; // 32bit CRC (computed over type and data)
  203. } rpng_chunk;
  204. // Color type
  205. // NOTE: Used for palette loading/saving
  206. typedef struct {
  207. unsigned char r; // Color red value
  208. unsigned char g; // Color green value
  209. unsigned char b; // Color blue value
  210. unsigned char a; // Color alpha value
  211. } rpng_color;
  212. // Palette type
  213. typedef struct {
  214. int color_count; // Palette color count
  215. rpng_color *colors; // Palette colors
  216. } rpng_palette;
  217. // A minimal PNG only requires: png_signature | rpng_chunk(IHDR) | rpng_chunk(IDAT) | rpng_chunk(IEND)
  218. #ifdef __cplusplus
  219. extern "C" { // Prevents name mangling of functions
  220. #endif
  221. //----------------------------------------------------------------------------------
  222. // Global Variables Definition
  223. //----------------------------------------------------------------------------------
  224. //...
  225. //----------------------------------------------------------------------------------
  226. // Module Functions Declaration
  227. //----------------------------------------------------------------------------------
  228. // Load a PNG file image data
  229. // - Color channels are returned by reference, supported values: 1 (GRAY), 2 (GRAY+ALPHA), 3 (RGB), 4 (RGBA)
  230. // - Bit depth is returned by reference, supported values: 8 bit, 16 bit
  231. // - In case data can not be loaded, returns NULL
  232. RPNGAPI char *rpng_load_image(const char *filename, int *width, int *height, int *color_channels, int *bit_depth);
  233. // Load a PNG file image data indexed (including palette)
  234. // - Returns indexed data as an index byte array (8bit) along the palette data (PLTE - RGB888 - 24bit)
  235. // - In case image data is not indexed, returns NULL
  236. RPNGAPI char *rpng_load_image_indexed(const char *filename, int *width, int *height, rpng_palette *palette);
  237. // Save a PNG file from image data (IHDR, IDAT, IEND)
  238. // - Color channels defines pixel color channels, supported values: 1 (GRAY), 2 (GRAY+ALPHA), 3 (RGB), 4 (RGBA)
  239. // - Bit depth defines every color channel size, supported values: 8 bit, 16 bit
  240. // - Returns saving process result: 0-SUCCESS
  241. RPNGAPI int rpng_save_image(const char *filename, const char *data, int width, int height, int color_channels, int bit_depth);
  242. // Save a PNG file from indexed image data (IHDR, PLTE, (tRNS), IDAT, IEND)
  243. // - Palette colours are saved as RGB888 in PLTE chunk
  244. // - Palette alpha is saved as R8 in tRNS chunk (if required)
  245. // - Palette max number of entries is limited to [1..256] colors
  246. // - Returns saving process result: 0-SUCCESS
  247. RPNGAPI int rpng_save_image_indexed(const char *filename, const char *indexed_data, int width, int height, rpng_palette palette);
  248. // Load and save png data from memory buffer
  249. // WARNING: Provided buffer is expected to be PNG compliant, ending with IEND chunk
  250. RPNGAPI char *rpng_load_image_from_memory(const char *buffer, int *width, int *height, int *color_channels, int *bit_depth); // Load png data from memory buffer
  251. RPNGAPI char *rpng_load_image_indexed_from_memory(const char *buffer, int *width, int *height, rpng_palette *palette); // Load indexed png data from memory buffer (8 bpp)
  252. RPNGAPI char *rpng_save_image_to_memory(const char *data, int width, int height, int color_channels, int bit_depth, int *output_size); // Save png data to memory buffer
  253. RPNGAPI char *rpng_save_image_indexed_to_memory(const char *indexed_data, int width, int height, rpng_palette palette, int *output_size); // Save indexed data to memory buffer
  254. // Convert indexed image data to RGBA data
  255. RPNGAPI char *rpng_unindex_image_data(char *indexed_data, int width, int height, rpng_palette palette);
  256. // Read and write chunks from file
  257. RPNGAPI int rpng_chunk_count(const char *filename); // Count the chunks in a PNG image
  258. RPNGAPI rpng_chunk rpng_chunk_read(const char *filename, const char *chunk_type); // Read one chunk type
  259. RPNGAPI rpng_chunk *rpng_chunk_read_all(const char *filename, int *count); // Read all chunks
  260. RPNGAPI void rpng_chunk_remove(const char *filename, const char *chunk_type); // Remove one chunk type
  261. RPNGAPI void rpng_chunk_remove_ancillary(const char *filename); // Remove all chunks except: IHDR-PLTE-IDAT-IEND
  262. RPNGAPI void rpng_chunk_write(const char *filename, rpng_chunk data); // Write one new chunk after IHDR (any kind)
  263. // Write specific chunks to file
  264. RPNGAPI void rpng_chunk_write_text(const char *filename, char *keyword, char *text); // Write tEXt chunk
  265. RPNGAPI void rpng_chunk_write_comp_text(const char *filename, char *keyword, char *text); // Write zTXt chunk, DEFLATE compressed text
  266. RPNGAPI void rpng_chunk_write_gamma(const char *filename, float gamma); // Write gAMA chunk (stored as int, gamma*100000)
  267. RPNGAPI void rpng_chunk_write_srgb(const char *filename, char srgb_type); // Write sRGB chunk, requires gAMA chunk
  268. RPNGAPI void rpng_chunk_write_time(const char *filename, short year, char month, char day, char hour, char min, char sec); // Write tIME chunk
  269. RPNGAPI void rpng_chunk_write_physical_size(const char *filename, int pixels_unit_x, int pixels_unit_y, bool meters); // Write pHYs chunk
  270. RPNGAPI void rpng_chunk_write_chroma(const char *filename, float white_x, float white_y, float red_x, float red_y, float green_x, float green_y, float blue_x, float blue_y); // Write cHRM chunk
  271. // Chunk utilities
  272. RPNGAPI void rpng_chunk_print_info(const char *filename); // Output info about the chunks
  273. RPNGAPI bool rpng_chunk_check_all_valid(const char *filename); // Check chunks CRC is valid
  274. RPNGAPI void rpng_chunk_combine_image_data(const char *filename); // Combine multiple IDAT chunks into a single one
  275. RPNGAPI void rpng_chunk_split_image_data(const char *filename, int split_size); // Split one IDAT chunk into multiple ones
  276. // Read and write chunks from memory buffer
  277. RPNGAPI int rpng_chunk_count_from_memory(const char *buffer); // Count the chunks in a PNG image from memory
  278. RPNGAPI rpng_chunk rpng_chunk_read_from_memory(const char *buffer, const char *chunk_type); // Read one chunk type from memory
  279. RPNGAPI rpng_chunk *rpng_chunk_read_all_from_memory(const char *buffer, int *count); // Read all chunks from memory
  280. RPNGAPI char *rpng_chunk_remove_from_memory(const char *buffer, const char *chunk_type, int *output_size); // Remove one chunk type from memory
  281. RPNGAPI char *rpng_chunk_remove_ancillary_from_memory(const char *buffer, int *output_size); // Remove all chunks except: IHDR-IDAT-IEND
  282. RPNGAPI char *rpng_chunk_write_from_memory(const char *buffer, rpng_chunk chunk, int *output_size); // Write one new chunk after IHDR (any kind)
  283. RPNGAPI char *rpng_chunk_combine_image_data_from_memory(char *buffer, int *output_size); // Combine multiple IDAT chunks into a single one
  284. RPNGAPI char *rpng_chunk_split_image_data_from_memory(char *buffer, int split_size, int *output_size); // Split one IDAT chunk into multiple ones
  285. #ifdef __cplusplus
  286. }
  287. #endif
  288. #endif // RPNG_H
  289. /***********************************************************************************
  290. *
  291. * RPNG IMPLEMENTATION
  292. *
  293. ************************************************************************************/
  294. #define RPNG_IMPLEMENTATION
  295. #if defined(RPNG_IMPLEMENTATION)
  296. #if !defined(RPNG_NO_STDIO)
  297. #include <stdio.h> // Required for: FILE, fopen(), fread(), fwrite(), fclose()
  298. #endif
  299. #include <stdlib.h> // Required for: malloc(), calloc(), free()
  300. #include <string.h> // Required for: memcmp(), memcpy()
  301. #if defined(_WIN32) && defined(_MSC_VER)
  302. #include <io.h> // Required for: _access() [file_exists()]
  303. #else
  304. #include <unistd.h> // Required for: access() (POSIX, not C standard) [file_exists()]
  305. #endif
  306. //----------------------------------------------------------------------------------
  307. // Types and Structures Definition
  308. //----------------------------------------------------------------------------------
  309. // NOTE: Some chunks strutures are defined for convenience,
  310. // but only the ones that can be directly serialized to chunk.dataa
  311. // Critical chunks (IHDR, PLTE, IDAT, IEND)
  312. //------------------------------------------------------------------------
  313. // IHDR: Image header
  314. // Mandatory chunk: image info (13 bytes)
  315. typedef struct {
  316. unsigned int width; // Image width
  317. unsigned int height; // Image width
  318. unsigned char bit_depth; // Bit depth
  319. unsigned char color_type; // Pixel format: 0 - Grayscale, 2 - RGB, 3 - Indexed, 4 - GrayAlpha, 6 - RGBA
  320. unsigned char compression; // Compression method: 0 (deflate)
  321. unsigned char filter; // Filter method: 0 (default)
  322. unsigned char interlace; // Interlace scheme (optional): 0 (none)
  323. // WARNING: 3 bytes of padding required for proper alignment!!!
  324. } rpng_chunk_IHDR;
  325. // PLTE: Palette
  326. // Contains from 1 to 256 palette entries, each a three-byte series (RGB)
  327. // Chunk must appear for color type 3, and can appear for color types 2 and 6; it must not appear for color types 0 and 4.
  328. // If this chunk does appear, it must precede the first IDAT chunk. There must not be more than one PLTE chunk
  329. // IDAT: Image data
  330. // There can be multiple IDAT chunks; if so, they must appear consecutively with no other intervening chunks
  331. // IEND: Image ending trailer
  332. // rpng_chunk_IEND > rpng_chunk (empty), it should be LAST
  333. // Transparency information
  334. //------------------------------------------------------------------------
  335. // tRNS: Transparency
  336. // For color type 3 (indexed color), the tRNS chunk contains a series of one-byte alpha values, corresponding to entries in the PLTE chunk.
  337. // For color type 0 (grayscale), the tRNS chunk contains a single gray level value, stored in the format: Gray (2 bytes), range 0 .. (2^bitdepth)-1
  338. // For color type 2 (truecolor), the tRNS chunk contains a single RGB color value, stored in the format: Red-Green-Blue (2 bytes each), range 0 .. (2^bitdepth)-1
  339. // tRNS is prohibited for color types 4 and 6, since a full alpha channel is already present in those cases.
  340. // When present, the tRNS chunk must precede the first IDAT chunk, and must follow the PLTE chunk, if any.
  341. // Color space information
  342. //------------------------------------------------------------------------
  343. // gAMA: Image gamma
  344. // Specifies the relationship between the image samples and the desired display output intensity as a power function: sample = light_out^gamma
  345. // Sample and light_out are normalized to the range 0.0 (minimum intensity) to 1.0 (maximum intensity). Therefore: sample = integer_sample/(2^bitdepth - 1)
  346. // cHRM: Primary chromaticities
  347. // NOTE: Values multiplied by 100000 (i.e. Value 0.3127 would be stored as the integer 31270)
  348. typedef struct {
  349. unsigned int white_point_x;
  350. unsigned int white_point_y;
  351. unsigned int redx;
  352. unsigned int redy;
  353. unsigned int greenx;
  354. unsigned int greeny;
  355. unsigned int bluex;
  356. unsigned int bluey;
  357. } rpng_chunk_cHRM;
  358. // sRGB: Standard RGB color space
  359. // When using sRGB chunk, gAMA should also be present (and perhaps a cHRM chunk)
  360. typedef struct {
  361. unsigned char flag; // 0: Perceptual, 1: Relative colorimetric, 2: Saturation, 3: Absolute colorimetric
  362. } rpng_chunk_sRGB;
  363. // iCCP: Embedded ICC profile
  364. // unsigned char *profile; // Profile name: 1-80 bytes (must end with NULL separator: /0)
  365. // unsigned char comp; // Compression method (0 for DEFLATE)
  366. // unsigned char *comp_profile; // Compressed profile: n bytes
  367. // Textual information
  368. //------------------------------------------------------------------------
  369. // tEXt: Textual data
  370. // unsigned char *keyword; // Keyword: 1-80 bytes (must end with NULL separator: /0)
  371. // unsigned char *text; // Text: n bytes (character string, no NULL terminated required)
  372. // zTXt: Compressed text data
  373. // unsigned char *keyword; // Keyword: 1-80 bytes (must end with NULL separator: /0)
  374. // unsigned char comp; // Compression method (0 for DEFLATE)
  375. // unsigned char *text; // UTF-8 text (0 or more bytes)
  376. // iTXt: International textual data
  377. // unsigned char *keyword; // Keyword: 1-80 bytes (must end with NULL separator: /0)
  378. // unsigned char comp_flag; // Compression flag (0 for uncompressed text, 1 for compressed text)
  379. // unsigned char comp; // Compression method (0 for DEFLATE)
  380. // unsigned char *lang_tag; // Language tag (0 or more bytes, must end with NULL separator: /0)
  381. // unsigned char *tr_keyword; // Translated keyword (0 or more bytes, must end with NULL separator: /0)
  382. // unsigned char *text; // UTF-8 text (0 or more bytes)
  383. // Miscellaneous information
  384. //------------------------------------------------------------------------
  385. // bKGD: Background color
  386. // Color type 3 (indexed color) -> Palette index: 1 byte
  387. // Color types 0 and 4 (gray or gray + alpha) -> Gray: 2 bytes, range 0 .. (2^bitdepth)-1
  388. // Color types 2 and 6 (truecolor, with or without alpha)
  389. // Red: 2 bytes, range 0 .. (2^bitdepth)-1
  390. // Green: 2 bytes, range 0 .. (2^bitdepth)-1
  391. // Blue: 2 bytes, range 0 .. (2^bitdepth)-1
  392. // pHYs: Physical pixel dimensions
  393. typedef struct {
  394. unsigned int pixels_per_unit_x;
  395. unsigned int pixels_per_unit_y;
  396. unsigned char unit_specifier; // 0 - Unit unknown, 1 - Unit is meter
  397. } rpng_chunk_pHYs;
  398. // tIME: Image last-modification time
  399. typedef struct {
  400. unsigned short year; // Year complete, i.e. 1995
  401. unsigned char month; // 1 to 12
  402. unsigned char day; // 1 to 31
  403. unsigned char hour; // 0 to 23
  404. unsigned char minute; // 0 to 59
  405. unsigned char second; // 0 to 60 (yes, 60, for leap seconds; not 61, a common error)
  406. } rpng_chunk_tIME;
  407. // Other chunks (view documentation)
  408. //sBIT: Significant bits
  409. //sPLT: Suggested palette
  410. //hIST: Palette histogram
  411. // TODO: Support APNG chunks
  412. // REF: https://wiki.mozilla.org/APNG_Specification
  413. //acTL: Animation Control
  414. //fcTL: Frame Control
  415. //fdAT: Frame Data
  416. //----------------------------------------------------------------------------------
  417. // Global Variables Definition
  418. //----------------------------------------------------------------------------------
  419. const unsigned char png_signature[8] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; // PNG Signature
  420. //----------------------------------------------------------------------------------
  421. // Module specific Functions Declaration
  422. //----------------------------------------------------------------------------------
  423. // Prefilter and compress image data (image_data -> IDAT chunk.data)
  424. static char *rpng_inflate_image_data(char *image_data, int image_data_size, int width, int height, int pixel_size);
  425. // Decompress and unfilter image data (IDAT chunk.data -> image_data)
  426. static char *rpng_deflate_image_data(const char *image_data, int image_data_size, int width, int height, int pixel_size, int *output_size, int forced_filter_type);
  427. // Swap integer from big<->little endian
  428. static unsigned int swap_endian(unsigned int value);
  429. static unsigned int compute_crc32(unsigned char *buffer, int size);
  430. // Load/save png file data from/to memory buffer
  431. static char *load_file_to_buffer(const char *filename, int *bytes_read);
  432. static int save_file_from_buffer(const char *filename, void *data, int bytesToWrite);
  433. static bool file_exists(const char *filename);
  434. // sdelf and sinfl implementations placed at the end of file
  435. #define SINFL_NO_SIMD
  436. #define SDEFL_IMPLEMENTATION
  437. #define SINFL_IMPLEMENTATION
  438. //===================================================================
  439. // SDEFL
  440. // DEFLATE COMPRESSION algorithm: https://github.com/vurtun/sdefl
  441. //===================================================================
  442. #define SDEFL_MAX_OFF (1 << 15)
  443. #define SDEFL_WIN_SIZ SDEFL_MAX_OFF
  444. #define SDEFL_WIN_MSK (SDEFL_WIN_SIZ-1)
  445. #define SDEFL_HASH_BITS 15
  446. #define SDEFL_HASH_SIZ (1 << SDEFL_HASH_BITS)
  447. #define SDEFL_HASH_MSK (SDEFL_HASH_SIZ-1)
  448. #define SDEFL_MIN_MATCH 4
  449. #define SDEFL_BLK_MAX (256*1024)
  450. #define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX+2)/3)
  451. #define SDEFL_SYM_MAX (288)
  452. #define SDEFL_OFF_MAX (32)
  453. #define SDEFL_PRE_MAX (19)
  454. #define SDEFL_LVL_MIN 0
  455. #define SDEFL_LVL_DEF 5
  456. #define SDEFL_LVL_MAX 8
  457. struct sdefl_freq {
  458. unsigned lit[SDEFL_SYM_MAX];
  459. unsigned off[SDEFL_OFF_MAX];
  460. };
  461. struct sdefl_code_words {
  462. unsigned lit[SDEFL_SYM_MAX];
  463. unsigned off[SDEFL_OFF_MAX];
  464. };
  465. struct sdefl_lens {
  466. unsigned char lit[SDEFL_SYM_MAX];
  467. unsigned char off[SDEFL_OFF_MAX];
  468. };
  469. struct sdefl_codes {
  470. struct sdefl_code_words word;
  471. struct sdefl_lens len;
  472. };
  473. struct sdefl_seqt {
  474. int off, len;
  475. };
  476. struct sdefl {
  477. int bits, bitcnt;
  478. int tbl[SDEFL_HASH_SIZ];
  479. int prv[SDEFL_WIN_SIZ];
  480. int seq_cnt;
  481. struct sdefl_seqt seq[SDEFL_SEQ_SIZ];
  482. struct sdefl_freq freq;
  483. struct sdefl_codes cod;
  484. };
  485. extern int sdefl_bound(int in_len);
  486. extern int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
  487. extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
  488. //=========================================================================
  489. // SINFL
  490. // DEFLATE DECOMPRESSION algorithm: https://github.com/vurtun/lib/sinfl.h
  491. //=========================================================================
  492. #define SINFL_PRE_TBL_SIZE 128
  493. #define SINFL_LIT_TBL_SIZE 1334
  494. #define SINFL_OFF_TBL_SIZE 402
  495. struct sinfl {
  496. const unsigned char *bitptr;
  497. unsigned long long bitbuf;
  498. int bitcnt;
  499. unsigned lits[SINFL_LIT_TBL_SIZE];
  500. unsigned dsts[SINFL_OFF_TBL_SIZE];
  501. };
  502. extern int sinflate(void *out, int cap, const void *in, int size);
  503. extern int zsinflate(void *out, int cap, const void *in, int size);
  504. //----------------------------------------------------------------------------------
  505. // Module Functions Definition
  506. //----------------------------------------------------------------------------------
  507. // The Paeth filter function computes a simple linear function of the three neighbouring pixels (left, above, upper left),
  508. // then chooses as predictor the neighbouring pixel closest to the computed value. Ref: https://www.w3.org/TR/PNG/#9Filters
  509. // The algorithm used in this International Standard is an adaptation of the technique due to Alan W. Paeth.
  510. // NOTE: Paeth predictor calculations shall be performed exactly, without overflow.
  511. static unsigned char rpng_paeth_predictor(int a, int b, int c)
  512. {
  513. unsigned char pr = 0;
  514. int p = a + b - c;
  515. int pa = abs(p - a);
  516. int pb = abs(p - b);
  517. int pc = abs(p - c);
  518. if ((pa <= pb) && (pa <= pc)) pr = (unsigned char)a;
  519. else if (pb <= pc) pr = (unsigned char)b;
  520. else pr = (unsigned char)c;
  521. return pr;
  522. }
  523. // Load a PNG file image data
  524. // - Color channels are returned by reference, supported values: 1 (GRAY), 2 (GRAY+ALPHA), 3 (RGB), 4 (RGBA)
  525. // - Bit depth is returned by reference, supported values: 8 bit, 16 bit
  526. char *rpng_load_image(const char *filename, int *width, int *height, int *color_channels, int *bit_depth)
  527. {
  528. char *data = NULL;
  529. int file_size = 0;
  530. char *file_data = load_file_to_buffer(filename, &file_size);
  531. if (file_data != NULL)
  532. {
  533. data = rpng_load_image_from_memory(file_data, width, height, color_channels, bit_depth);
  534. RPNG_FREE(file_data);
  535. }
  536. return data;
  537. }
  538. // Load a PNG file image data indexed (including palette)
  539. // - Returns indexed data as an index byte array (8bit) along the palette data (PLTE - RGB888 - 24bit)
  540. // WARNING: In case data is not indexed, returns NULL for pointers and sets values to 0
  541. char *rpng_load_image_indexed(const char *filename, int *width, int *height, rpng_palette *palette)
  542. {
  543. char *data = NULL;
  544. int file_size = 0;
  545. char *file_data = load_file_to_buffer(filename, &file_size);
  546. if (file_data != NULL)
  547. {
  548. data = rpng_load_image_indexed_from_memory(file_data, width, height, palette);
  549. RPNG_FREE(file_data);
  550. }
  551. return data;
  552. }
  553. // Save a PNG file from image data (IHDR, IDAT, IEND)
  554. // - Color channels defines pixel color channels, supported values: 1 (GRAY), 2 (GRAY+ALPHA), 3 (RGB), 4 (RGBA)
  555. // - Bit depth defines every color channel size, supported values: 8 bit, 16 bit
  556. int rpng_save_image(const char *filename, const char *data, int width, int height, int color_channels, int bit_depth)
  557. {
  558. int result = 0;
  559. int file_output_size = 0;
  560. char *file_output = rpng_save_image_to_memory(data, width, height, color_channels, bit_depth, &file_output_size);
  561. if ((file_output != NULL) && (file_output_size > 0))
  562. {
  563. save_file_from_buffer(filename, file_output, file_output_size);
  564. }
  565. else RPNG_LOG("WARNING: PNG data saving failed");
  566. RPNG_FREE(file_output);
  567. return result;
  568. }
  569. // Save a PNG file from indexed image data (IHDR, PLTE, (tRNS), IDAT, IEND)
  570. // - Palette colours are saved as RGB888 in PLTE chunk
  571. // - Palette alpha is saved as R8 in tRNS chunk (if required)
  572. // - Palette max number of entries is limited to [1..256] colors
  573. int rpng_save_image_indexed(const char *filename, const char *indexed_data, int width, int height, rpng_palette palette)
  574. {
  575. int result = 0;
  576. int file_output_size = 0;
  577. char *file_output = rpng_save_image_indexed_to_memory(indexed_data, width, height, palette, &file_output_size);
  578. if ((file_output != NULL) && (file_output_size > 0))
  579. {
  580. save_file_from_buffer(filename, file_output, file_output_size);
  581. }
  582. else RPNG_LOG("WARNING: PNG data saving failed");
  583. RPNG_FREE(file_output);
  584. return result;
  585. }
  586. // Count number of PNG chunks
  587. int rpng_chunk_count(const char *filename)
  588. {
  589. int count = 0;
  590. int file_size = 0;
  591. char *file_data = load_file_to_buffer(filename, &file_size);
  592. if (file_data != NULL)
  593. {
  594. count = rpng_chunk_count_from_memory(file_data);
  595. RPNG_FREE(file_data);
  596. }
  597. return count;
  598. }
  599. // Read one chunk from a PNG file
  600. // NOTE: There could be multiple chunks of same type, only first found is returned
  601. rpng_chunk rpng_chunk_read(const char *filename, const char *chunk_type)
  602. {
  603. rpng_chunk chunk = { 0 };
  604. int file_size = 0;
  605. char *file_data = load_file_to_buffer(filename, &file_size);
  606. if (file_data != NULL)
  607. {
  608. chunk = rpng_chunk_read_from_memory(file_data, chunk_type);
  609. RPNG_FREE(file_data);
  610. }
  611. return chunk;
  612. }
  613. // Read all chunks from a PNG file
  614. rpng_chunk *rpng_chunk_read_all(const char *filename, int *count)
  615. {
  616. int counter = 0;
  617. rpng_chunk *chunks = NULL;
  618. int file_size = 0;
  619. char *file_data = load_file_to_buffer(filename, &file_size);
  620. if (file_data != NULL)
  621. {
  622. chunks = rpng_chunk_read_all_from_memory(file_data, &counter);
  623. RPNG_FREE(file_data);
  624. }
  625. *count = counter;
  626. return chunks;
  627. }
  628. // Remove text chunk by type
  629. void rpng_chunk_remove(const char *filename, const char *chunk_type)
  630. {
  631. int file_size = 0;
  632. char *file_data = load_file_to_buffer(filename, &file_size);
  633. if (file_data != NULL)
  634. {
  635. int file_output_size = 0;
  636. char *file_output = rpng_chunk_remove_from_memory(file_data, chunk_type, &file_output_size);
  637. save_file_from_buffer(filename, file_output, file_output_size);
  638. RPNG_FREE(file_output);
  639. RPNG_FREE(file_data);
  640. }
  641. }
  642. // Remove all chunks except: IHDR-IDAT-IEND
  643. void rpng_chunk_remove_ancillary(const char *filename)
  644. {
  645. int file_size = 0;
  646. char *file_data = load_file_to_buffer(filename, &file_size);
  647. if (file_data != NULL)
  648. {
  649. int file_output_size = 0;
  650. char *file_output = rpng_chunk_remove_ancillary_from_memory(file_data, &file_output_size);
  651. save_file_from_buffer(filename, file_output, file_output_size);
  652. RPNG_FREE(file_output);
  653. RPNG_FREE(file_data);
  654. }
  655. }
  656. // Add one new chunk (any kind)
  657. // NOTE: Chunk is added by default after IHDR
  658. void rpng_chunk_write(const char *filename, rpng_chunk chunk)
  659. {
  660. int file_size = 0;
  661. char *file_data = load_file_to_buffer(filename, &file_size);
  662. int file_output_size = 0;
  663. char *file_output = NULL;
  664. if (file_data != NULL)
  665. {
  666. file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  667. // Verify expected output size before writing to file
  668. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  669. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  670. RPNG_FREE(file_output);
  671. RPNG_FREE(file_data);
  672. }
  673. }
  674. // Write text chunk data into PNG
  675. // NOTE: It will be added just after IHDR chunk
  676. // tEXt chunk data:
  677. // unsigned char *keyword; // Keyword: 1-80 bytes (must end with NULL separator: /0)
  678. // unsigned char *text; // Text: n bytes (character string, no NULL terminated required)
  679. // Keyword/Text usual values:
  680. // Title Short (one line) title or caption for image
  681. // Author Name of image's creator
  682. // Description Description of image (possibly long)
  683. // Copyright Copyright notice
  684. // Creation Time Time of original image creation
  685. // Software Software used to create the image
  686. // Disclaimer Legal disclaimer
  687. // Warning Warning of nature of content
  688. // Source Device used to create the image
  689. // Comment Miscellaneous comment
  690. void rpng_chunk_write_text(const char *filename, char *keyword, char *text)
  691. {
  692. int file_size = 0;
  693. char *file_data = load_file_to_buffer(filename, &file_size);
  694. if (file_data != NULL)
  695. {
  696. rpng_chunk chunk = { 0 };
  697. int keyword_len = (int)strlen(keyword);
  698. int text_len = (int)strlen(text);
  699. // Fill chunk with required data
  700. // NOTE: CRC can be left to 0, it's calculated internally on writing
  701. memcpy(chunk.type, "tEXt", 4);
  702. chunk.length = keyword_len + 1 + text_len;
  703. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  704. memcpy(chunk.data, keyword, keyword_len);
  705. memcpy(chunk.data + keyword_len + 1, text, text_len);
  706. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  707. int file_output_size = 0;
  708. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  709. // Verify expected output size before writing to file
  710. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  711. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  712. RPNG_FREE(chunk.data);
  713. RPNG_FREE(file_output);
  714. RPNG_FREE(file_data);
  715. }
  716. }
  717. // Write zTXt chunk, DEFLATE compressed text
  718. // zTXt chunk information and size:
  719. // unsigned char *keyword; // Keyword: 1-80 bytes (must end with NULL separator: /0)
  720. // unsigned char comp; // Compression method (0 for DEFLATE)
  721. // unsigned char *comp_text; // Compressed text: n bytes
  722. void rpng_chunk_write_comp_text(const char *filename, char *keyword, char *text)
  723. {
  724. int file_size = 0;
  725. char *file_data = load_file_to_buffer(filename, &file_size);
  726. if (file_data != NULL)
  727. {
  728. // Create chunk and fill with data
  729. rpng_chunk chunk = { 0 };
  730. int keyword_len = (int)strlen(keyword);
  731. int text_len = (int)strlen(text);
  732. // Compress filtered image data and generate a valid zlib stream
  733. struct sdefl *sde = (struct sdefl *)RPNG_CALLOC(sizeof(struct sdefl), 1);
  734. int bounds = sdefl_bound(text_len);
  735. unsigned char *comp_text = (unsigned char *)RPNG_CALLOC(bounds, 1);
  736. int comp_text_size = zsdeflate(sde, comp_text, (unsigned char *)text, text_len, RPNG_COMPRESSION_LEVEL);
  737. RPNG_FREE(sde);
  738. // Fill chunk with required data
  739. // NOTE: CRC can be left to 0, it's calculated internally on writing
  740. memcpy(chunk.type, "zTXt", 4);
  741. chunk.length = keyword_len + 1 + 1 + comp_text_size;
  742. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  743. memcpy(chunk.data, keyword, keyword_len);
  744. memcpy(chunk.data + keyword_len + 2, comp_text, comp_text_size);
  745. int file_output_size = 0;
  746. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  747. // Verify expected output size before writing to file
  748. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  749. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  750. RPNG_FREE(chunk.data);
  751. RPNG_FREE(comp_text);
  752. RPNG_FREE(file_output);
  753. RPNG_FREE(file_data);
  754. }
  755. }
  756. // Write gAMA chunk
  757. // NOTE: Gamma is stored as one int: gamma*100000
  758. void rpng_chunk_write_gamma(const char *filename, float gamma)
  759. {
  760. int file_size = 0;
  761. char *file_data = load_file_to_buffer(filename, &file_size);
  762. if (file_data != NULL)
  763. {
  764. rpng_chunk chunk = { 0 };
  765. int gamma_value = (int)(gamma*100000);
  766. // Fill chunk with required data
  767. // NOTE: CRC can be left to 0, it's calculated internally on writing
  768. memcpy(chunk.type, "gAMA", 4);
  769. chunk.length = 4;
  770. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  771. gamma_value = swap_endian(gamma_value);
  772. memcpy(chunk.data, &gamma_value, 4);
  773. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  774. int file_output_size = 0;
  775. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  776. // Verify expected output size before writing to file
  777. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  778. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  779. RPNG_FREE(chunk.data);
  780. RPNG_FREE(file_output);
  781. RPNG_FREE(file_data);
  782. }
  783. }
  784. // Write sRGB chunk, requires gAMA chunk
  785. // NOTE: This chunk only contains 1 byte of data defining rendering intent:
  786. // 0: Perceptual
  787. // 1: Relative colorimetric
  788. // 2: Saturation
  789. // 3: Absolute colorimetric
  790. void rpng_chunk_write_srgb(const char *filename, char srgb_type)
  791. {
  792. int file_size = 0;
  793. char *file_data = load_file_to_buffer(filename, &file_size);
  794. rpng_chunk chunk = { 0 };
  795. if ((srgb_type < 0) || (srgb_type > 3)) srgb_type = 0;
  796. // Fill chunk with required data
  797. // NOTE: CRC can be left to 0, it's calculated internally on writing
  798. memcpy(chunk.type, "sRGB", 4);
  799. chunk.length = 1;
  800. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  801. memcpy(chunk.data, &srgb_type, 1);
  802. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  803. int file_output_size = 0;
  804. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  805. // Verify expected output size before writing to file
  806. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  807. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  808. RPNG_FREE(chunk.data);
  809. RPNG_FREE(file_output);
  810. RPNG_FREE(file_data);
  811. }
  812. // Write tIME chunk
  813. // tIME chunk information and size:
  814. // unsigned short year; // Year complete, i.e. 1995
  815. // unsigned char month; // 1 to 12
  816. // unsigned char day; // 1 to 31
  817. // unsigned char hour; // 0 to 23
  818. // unsigned char minute; // 0 to 59
  819. // unsigned char second; // 0 to 60 (yes, 60, for leap seconds; not 61, a common error)
  820. void rpng_chunk_write_time(const char *filename, short year, char month, char day, char hour, char min, char sec)
  821. {
  822. int file_size = 0;
  823. char *file_data = load_file_to_buffer(filename, &file_size);
  824. rpng_chunk chunk = { 0 };
  825. // Fill chunk with required data
  826. // NOTE: CRC can be left to 0, it's calculated internally on writing
  827. memcpy(chunk.type, "tIME", 4);
  828. chunk.length = 7;
  829. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  830. memcpy(chunk.data, &year, 2);
  831. memcpy(chunk.data + 2, &month, 1);
  832. memcpy(chunk.data + 3, &day, 1);
  833. memcpy(chunk.data + 4, &hour, 1);
  834. memcpy(chunk.data + 5, &min, 1);
  835. memcpy(chunk.data + 6, &sec, 1);
  836. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  837. int file_output_size = 0;
  838. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  839. // Verify expected output size before writing to file
  840. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  841. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  842. RPNG_FREE(chunk.data);
  843. RPNG_FREE(file_output);
  844. RPNG_FREE(file_data);
  845. }
  846. // Write pHYs chunk
  847. // pHYs chunk information and size:
  848. // unsigned int pixels_per_unit_x;
  849. // unsigned int pixels_per_unit_y;
  850. // unsigned char unit_specifier; // 0 - Unit unknown, 1 - Unit is meter
  851. void rpng_chunk_write_physical_size(const char *filename, int pixels_unit_x, int pixels_unit_y, bool meters)
  852. {
  853. int file_size = 0;
  854. char *file_data = load_file_to_buffer(filename, &file_size);
  855. rpng_chunk chunk = { 0 };
  856. // Fill chunk with required data
  857. // NOTE: CRC can be left to 0, it's calculated internally on writing
  858. memcpy(chunk.type, "pHYs", 4);
  859. chunk.length = 9;
  860. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  861. pixels_unit_x = swap_endian(pixels_unit_x);
  862. memcpy(chunk.data, &pixels_unit_x, 4);
  863. pixels_unit_y = swap_endian(pixels_unit_y);
  864. memcpy(chunk.data + 4, &pixels_unit_y, 4);
  865. char meters_value = (meters)? 1 : 0;
  866. memcpy(chunk.data + 8, &meters_value, 1);
  867. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  868. int file_output_size = 0;
  869. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  870. // Verify expected output size before writing to file
  871. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  872. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  873. RPNG_FREE(chunk.data);
  874. RPNG_FREE(file_output);
  875. RPNG_FREE(file_data);
  876. }
  877. // Write cHRM chunk
  878. // cHRM chunk information and size:
  879. // unsigned int white_point_x;
  880. // unsigned int white_point_y;
  881. // unsigned int redx;
  882. // unsigned int redy;
  883. // unsigned int greenx;
  884. // unsigned int greeny;
  885. // unsigned int bluex;
  886. // unsigned int bluey;
  887. // NOTE: Each value is stored as one int: value*100000
  888. void rpng_chunk_write_chroma(const char *filename, float white_x, float white_y, float red_x, float red_y, float green_x, float green_y, float blue_x, float blue_y)
  889. {
  890. int file_size = 0;
  891. char *file_data = load_file_to_buffer(filename, &file_size);
  892. rpng_chunk chunk = { 0 };
  893. // Fill chunk with required data
  894. // NOTE: CRC can be left to 0, it's calculated internally on writing
  895. memcpy(chunk.type, "pHYs", 4);
  896. chunk.length = 8*4; // 8 integer values
  897. chunk.data = (char *)RPNG_CALLOC(chunk.length, 1);
  898. int white_x_value = swap_endian((int)(white_x*100000));
  899. memcpy(chunk.data, &white_x_value, 4);
  900. int white_y_value = swap_endian((int)(white_y*100000));
  901. memcpy(chunk.data + 4, &white_y_value, 4);
  902. int red_x_value = swap_endian((int)(red_x*100000));
  903. memcpy(chunk.data + 8, &red_x_value, 4);
  904. int red_y_value = swap_endian((int)(red_y*100000));
  905. memcpy(chunk.data + 12, &red_y_value, 4);
  906. int green_x_value = swap_endian((int)(green_x*100000));
  907. memcpy(chunk.data + 16, &green_x_value, 4);
  908. int green_y_value = swap_endian((int)(green_y*100000));
  909. memcpy(chunk.data + 20, &green_y_value, 4);
  910. int blue_x_value = swap_endian((int)(blue_x*100000));
  911. memcpy(chunk.data + 24, &blue_x_value, 4);
  912. int blue_y_value = swap_endian((int)(blue_y*100000));
  913. memcpy(chunk.data + 28, &blue_y_value, 4);
  914. chunk.crc = 0; // Computed by rpng_chunk_write_from_memory()
  915. int file_output_size = 0;
  916. char *file_output = rpng_chunk_write_from_memory(file_data, chunk, &file_output_size);
  917. // Verify expected output size before writing to file
  918. if (file_output_size == (file_size + chunk.length + 12)) save_file_from_buffer(filename, file_output, file_output_size);
  919. else RPNG_LOG("WARNING: Failed to save file, output size not matching expected size\n");
  920. RPNG_FREE(chunk.data);
  921. RPNG_FREE(file_output);
  922. RPNG_FREE(file_data);
  923. }
  924. // Output info about the chunks
  925. void rpng_chunk_print_info(const char *filename)
  926. {
  927. int count = 0;
  928. rpng_chunk *chunks = rpng_chunk_read_all(filename, &count);
  929. if (chunks == NULL) return;
  930. RPNG_LOG("\n| Chunk | Data Length | CRC32 |\n");
  931. RPNG_LOG("|-------|----------------|-----------|\n");
  932. for (int i = 0; i < count; i++)
  933. {
  934. RPNG_LOG("| %c%c%c%c | %8i bytes | %08X |\n", chunks[i].type[0], chunks[i].type[1], chunks[i].type[2], chunks[i].type[3], chunks[i].length, chunks[i].crc);
  935. }
  936. RPNG_LOG("\n");
  937. /*
  938. rpng_chunk_IHDR *IHDRData = (rpng_chunk_IHDR *)chunks[0].data;
  939. RPNG_LOG("\n| IHDR information |\n");
  940. RPNG_LOG("|---------------------|\n");
  941. RPNG_LOG("| width: %4i |\n", swap_endian(IHDRData->width)); // Image width
  942. RPNG_LOG("| weight: %4i |\n", swap_endian(IHDRData->height)); // Image height
  943. RPNG_LOG("| bit depth: %4i |\n", IHDRData->bit_depth); // Bit depth
  944. RPNG_LOG("| color type: %4i |\n", IHDRData->color_type); // Pixel format: 0-Grayscale, 2-RGB, 3-Indexed, 4-GrayAlpha, 6-RGBA
  945. RPNG_LOG("| compression: %i |\n", IHDRData->compression); // Compression method: 0
  946. RPNG_LOG("| filter method: %i |\n", IHDRData->filter); // Filter method: 0 (default)
  947. RPNG_LOG("| interlace: %i |\n", IHDRData->interlace); // Interlace scheme (optional): 0 (none)
  948. */
  949. for (int i = 0; i < count; i++) RPNG_FREE(chunks[i].data);
  950. RPNG_FREE(chunks);
  951. }
  952. // Check chunks CRC and order
  953. bool rpng_chunk_check_all_valid(const char *filename)
  954. {
  955. bool result = true;
  956. int count = 0;
  957. rpng_chunk *chunks = rpng_chunk_read_all(filename, &count);
  958. if (chunks == NULL) return false;
  959. unsigned int crc = 0;
  960. char *chunk_type_data = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1);
  961. if (chunk_type_data != NULL)
  962. {
  963. for (int i = 0; i < count; i++)
  964. {
  965. memcpy(chunk_type_data, chunks[i].type, 4);
  966. memcpy(chunk_type_data + 4, chunks[i].data, chunks[i].length);
  967. crc = compute_crc32((unsigned char *)chunk_type_data, 4 + chunks[i].length);
  968. crc = swap_endian(crc);
  969. // Check computed CRC matches provided CRC
  970. if (chunks[i].crc != crc)
  971. {
  972. result = false;
  973. break;
  974. }
  975. }
  976. }
  977. // Free chunks memory
  978. for (int i = 0; i < count; i++) RPNG_FREE(chunks[i].data);
  979. RPNG_FREE(chunks);
  980. return result;
  981. }
  982. // Combine multiple IDAT chunks into a single one
  983. void rpng_chunk_combine_image_data(const char *filename)
  984. {
  985. int file_size = 0;
  986. char *file_data = load_file_to_buffer(filename, &file_size);
  987. if (file_data != NULL)
  988. {
  989. int file_output_size = 0;
  990. char *file_output = rpng_chunk_combine_image_data_from_memory(file_data, &file_output_size);
  991. // Verify process worked as expected
  992. if ((file_output != NULL) && (file_output_size == file_size))
  993. {
  994. save_file_from_buffer(filename, file_output, file_output_size);
  995. }
  996. RPNG_FREE(file_output);
  997. RPNG_FREE(file_data);
  998. }
  999. }
  1000. // Split one IDAT chunk into multiple ones
  1001. void rpng_chunk_split_image_data(const char *filename, int split_size)
  1002. {
  1003. int file_size = 0;
  1004. char *file_data = load_file_to_buffer(filename, &file_size);
  1005. if (file_data != NULL)
  1006. {
  1007. int file_output_size = 0;
  1008. char *file_output = rpng_chunk_split_image_data_from_memory(file_data, split_size, &file_output_size);
  1009. // Verify process worked as expected
  1010. if ((file_output != 0) && (file_output_size > file_size))
  1011. {
  1012. save_file_from_buffer(filename, file_output, file_output_size);
  1013. }
  1014. RPNG_FREE(file_output);
  1015. RPNG_FREE(file_data);
  1016. }
  1017. }
  1018. // Functions operating on memory buffers data
  1019. //----------------------------------------------------------------------------------------------------------
  1020. // Load png data from memory buffer
  1021. char *rpng_load_image_from_memory(const char *buffer, int *width, int *height, int *color_channels, int *bit_depth)
  1022. {
  1023. char *data = NULL;
  1024. rpng_chunk chunk_info = rpng_chunk_read_from_memory(buffer, "IHDR");
  1025. if (chunk_info.data == NULL) return data; // WARNING: Return if no info chunk has been loaded
  1026. // First chunk is always IHDR, we can check image data info
  1027. rpng_chunk_IHDR *IHDRData = (rpng_chunk_IHDR *)chunk_info.data;
  1028. *width = swap_endian(IHDRData->width); // Image width
  1029. *height = swap_endian(IHDRData->height); // Image height
  1030. *bit_depth = IHDRData->bit_depth; // Bit depth
  1031. *color_channels = 0;
  1032. switch (IHDRData->color_type)
  1033. {
  1034. case 0: *color_channels = 1; break; // Pixel format: 0-Grayscale
  1035. case 4: *color_channels = 2; break; // Pixel format: 4-GrayAlpha
  1036. case 2: *color_channels = 3; break; // Pixel format: 2-RGB
  1037. case 6: *color_channels = 4; break; // Pixel format: 6-RGBA
  1038. case 3: *color_channels = 1; break; // Pixel format: 3-Indexed (1 channel containing 8-bit indexed data)
  1039. default: break;
  1040. }
  1041. // TODO: Support bit depths of 1/2/4 bits? -> Convert to 8bit grayscale
  1042. if ((*color_channels == 1) && (*bit_depth != 8) && (*bit_depth != 16)) return data; // Bit depth 1/2/4 not supported
  1043. // Additional info provided by IHDR (in case it was required)
  1044. //IHDRData->compression; // Compression method: 0 (DEFLATE)
  1045. //IHDRData->filter; // Filter method: 0 (default)
  1046. //IHDRData->interlace; // Interlace scheme (optional): 0 (none)
  1047. if (*color_channels != 0)
  1048. {
  1049. // NOTE: All splitted chunks are joined on reading
  1050. rpng_chunk chunk_image = rpng_chunk_read_from_memory(buffer, "IDAT");
  1051. if (chunk_image.data != NULL)
  1052. {
  1053. // Verify data integrity CRC over all chunk data concatenated
  1054. unsigned int crc = 0;
  1055. char *chunk_type_data = (char *)RPNG_CALLOC(4 + chunk_image.length, 1);
  1056. memcpy(chunk_type_data, chunk_image.type, 4);
  1057. memcpy(chunk_type_data + 4, chunk_image.data, chunk_image.length);
  1058. crc = compute_crc32((unsigned char *)chunk_type_data, 4 + chunk_image.length);
  1059. RPNG_FREE(chunk_type_data);
  1060. if (crc == chunk_image.crc) // Validate crc
  1061. {
  1062. int pixel_size = *color_channels*(*bit_depth/8);
  1063. data = rpng_inflate_image_data(chunk_image.data, chunk_image.length, *width, *height, pixel_size);
  1064. if (data == NULL) RPNG_LOG("WARNING: IDAT image data decompression failed\n");
  1065. }
  1066. else RPNG_LOG("WARNING: CRC not valid, IDAT chunk image data could be corrupted\n");
  1067. }
  1068. RPNG_FREE(chunk_image.data);
  1069. }
  1070. else RPNG_LOG("WARNING: Failed to load file, image pixel format not supported\n");
  1071. RPNG_FREE(chunk_info.data);
  1072. return data;
  1073. }
  1074. // Load indexed png data (including palette) from memory buffer
  1075. // NOTE: Returns indexed data as an index byte array (8bit) along the palette data (PLTE - RGB888 - 24bit)
  1076. char *rpng_load_image_indexed_from_memory(const char *buffer, int *width, int *height, rpng_palette *palette)
  1077. {
  1078. char *data = NULL;
  1079. *width = 0;
  1080. *height = 0;
  1081. // Load indexed palette data, if provided
  1082. // Start verifying it contains palette/indexed data, if not we finish
  1083. rpng_chunk chunk_palette = rpng_chunk_read_from_memory(buffer, "PLTE");
  1084. if (chunk_palette.data != NULL)
  1085. {
  1086. // Palette data is provided as RGB888
  1087. palette->color_count = chunk_palette.length/3;
  1088. palette->colors = (rpng_color *)RPNG_CALLOC(palette->color_count, sizeof(rpng_color));
  1089. for (int i = 0; i < palette->color_count; i++)
  1090. {
  1091. palette->colors[i].r = chunk_palette.data[i*3 + 0];
  1092. palette->colors[i].g = chunk_palette.data[i*3 + 1];
  1093. palette->colors[i].b = chunk_palette.data[i*3 + 2];
  1094. palette->colors[i].a = 255;
  1095. }
  1096. RPNG_FREE(chunk_palette.data);
  1097. // Try loading palette alpha data, if provided
  1098. rpng_chunk chunk_alpha = rpng_chunk_read_from_memory(buffer, "tRNS");
  1099. if ((chunk_alpha.data != NULL) && (chunk_alpha.length == palette->color_count))
  1100. {
  1101. for (int i = 0; i < palette->color_count; i++) palette->colors[i].a = (unsigned char)chunk_alpha.data[i];
  1102. RPNG_FREE(chunk_alpha.data);
  1103. }
  1104. // Load indexed image data
  1105. rpng_chunk chunk_info = rpng_chunk_read_from_memory(buffer, "IHDR");
  1106. // WARNING: Cast chunk_info data directly to expected IHDR struct layout
  1107. rpng_chunk_IHDR *IHDRData = (rpng_chunk_IHDR *)chunk_info.data;
  1108. *width = swap_endian(IHDRData->width); // Image width
  1109. *height = swap_endian(IHDRData->height); // Image height
  1110. // Verify color type is indexed (3) and bit depth is 8
  1111. if ((IHDRData->color_type == 3) && (IHDRData->bit_depth == 8))
  1112. {
  1113. // NOTE: All splitted chunks are joined on reading
  1114. rpng_chunk chunk_image = rpng_chunk_read_from_memory(buffer, "IDAT");
  1115. if (chunk_image.data != NULL)
  1116. {
  1117. // Verify data integrity CRC over all chunk data concatenated
  1118. unsigned int crc = 0;
  1119. char *chunk_type_data = (char *)RPNG_CALLOC(4 + chunk_image.length, 1);
  1120. memcpy(chunk_type_data, chunk_image.type, 4);
  1121. memcpy(chunk_type_data + 4, chunk_image.data, chunk_image.length);
  1122. crc = compute_crc32((unsigned char *)chunk_type_data, 4 + chunk_image.length);
  1123. RPNG_FREE(chunk_type_data);
  1124. if (crc == chunk_image.crc) // Validate crc
  1125. {
  1126. int pixel_size = (IHDRData->bit_depth/8); // NOTE: Assume 1 channel
  1127. data = rpng_inflate_image_data(chunk_image.data, chunk_image.length, *width, *height, pixel_size);
  1128. if (data == NULL) RPNG_LOG("WARNING: IDAT image data �decompression failed\n");
  1129. }
  1130. else RPNG_LOG("WARNING: CRC not valid, IDAT chunk image data could be corrupted\n");
  1131. }
  1132. RPNG_FREE(chunk_image.data);
  1133. }
  1134. RPNG_FREE(chunk_info.data);
  1135. }
  1136. return data;
  1137. }
  1138. // Save png data to memory buffer
  1139. char *rpng_save_image_to_memory(const char *data, int width, int height, int color_channels, int bit_depth, int *output_size)
  1140. {
  1141. char *output_buffer = NULL;
  1142. int output_buffer_size = 0;
  1143. if ((bit_depth != 8) && (bit_depth != 16))
  1144. {
  1145. RPNG_LOG("WARNING: Requested bit depth (%i bit per channel) not supported\n", bit_depth);
  1146. return output_buffer; // WARNING: Bit depth 1/2/4 not supported
  1147. }
  1148. int color_type = -1;
  1149. if (color_channels == 1) color_type = 0; // Grayscale
  1150. else if (color_channels == 2) color_type = 4; // Gray + Alpha
  1151. else if (color_channels == 3) color_type = 2; // RGB
  1152. else if (color_channels == 4) color_type = 6; // RGBA
  1153. if (color_type == -1) return output_buffer; // WARNING: Number of channels not supported
  1154. rpng_chunk_IHDR image_info = { 0 };
  1155. image_info.width = swap_endian(width);
  1156. image_info.height = swap_endian(height);
  1157. image_info.bit_depth = (unsigned char)bit_depth;
  1158. image_info.color_type = (unsigned char)color_type;
  1159. // Image data pre-processing to append filter type byte to every scanline
  1160. int pixel_size = color_channels*(bit_depth/8);
  1161. int comp_data_size = 0;
  1162. char *comp_data = rpng_deflate_image_data(data, width*height*pixel_size, width, height, pixel_size, &comp_data_size, -1);
  1163. // Security check to verify compression worked
  1164. if ((comp_data != NULL) && (comp_data_size > 0))
  1165. {
  1166. output_buffer = (char *)RPNG_CALLOC(8 + 13 + 12 + (comp_data_size + 12) + 12, 1); // Signature + IHDR + IDAT + IEND
  1167. // Write PNG signature
  1168. memcpy(output_buffer, png_signature, 8);
  1169. // Write PNG chunk IHDR
  1170. unsigned int length_IHDR = 13;
  1171. length_IHDR = swap_endian(length_IHDR);
  1172. memcpy(output_buffer + 8, &length_IHDR, 4);
  1173. memcpy(output_buffer + 8 + 4, "IHDR", 4);
  1174. memcpy(output_buffer + 8 + 4 + 4, &image_info, 13);
  1175. unsigned int crc = compute_crc32((unsigned char *)output_buffer + 8 + 4, 4 + 13);
  1176. crc = swap_endian(crc);
  1177. memcpy(output_buffer + 8 + 8 + 13, &crc, 4);
  1178. output_buffer_size += (8 + 12 + 13);
  1179. // Write PNG chunk IDAT
  1180. unsigned int length_IDAT = comp_data_size;
  1181. length_IDAT = swap_endian(length_IDAT);
  1182. memcpy(output_buffer + output_buffer_size, &length_IDAT, 4);
  1183. memcpy(output_buffer + output_buffer_size + 4, "IDAT", 4);
  1184. memcpy(output_buffer + output_buffer_size + 8, comp_data, comp_data_size);
  1185. crc = compute_crc32((unsigned char *)output_buffer + output_buffer_size + 4, 4 + comp_data_size);
  1186. crc = swap_endian(crc);
  1187. memcpy(output_buffer + output_buffer_size + 8 + comp_data_size, &crc, 4);
  1188. output_buffer_size += (comp_data_size + 12);
  1189. // Write PNG chunk IEND
  1190. unsigned char chunk_IEND[12] = { 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82 };
  1191. memcpy(output_buffer + output_buffer_size, chunk_IEND, 12);
  1192. output_buffer_size += 12;
  1193. }
  1194. RPNG_FREE(comp_data);
  1195. *output_size = output_buffer_size;
  1196. return output_buffer;
  1197. }
  1198. // Save indexed png data to memory buffer
  1199. char *rpng_save_image_indexed_to_memory(const char *indexed_data, int width, int height, rpng_palette palette, int *output_size)
  1200. {
  1201. char *output_buffer = NULL;
  1202. int output_buffer_size = 0;
  1203. rpng_chunk_IHDR image_info = { 0 };
  1204. image_info.width = swap_endian(width);
  1205. image_info.height = swap_endian(height);
  1206. image_info.bit_depth = 8; // WARNING: Indexed data assumes 8-bit indexes
  1207. image_info.color_type = 3; // NOTE: Indexed data requires 3
  1208. // Image data pre-processing to append filter type byte to every scanline
  1209. int pixel_size = 1; // 1 byte per pixel (indexed data)
  1210. int comp_data_size = 0;
  1211. char *comp_data = rpng_deflate_image_data(indexed_data, width*height*pixel_size, width, height, pixel_size, &comp_data_size, 0);
  1212. // Security check to verify compression worked
  1213. if ((comp_data != NULL) && (comp_data_size > 0))
  1214. {
  1215. // Verify if tRNS chunk with palette alpha values is required (if there is any alpha != 255)
  1216. bool trns_required = false;
  1217. for (int i = 0; i < palette.color_count; i++)
  1218. {
  1219. if (palette.colors[i].a != 255) { trns_required = true; break; }
  1220. }
  1221. // Allocate output buffer at required size
  1222. output_buffer = (char *)RPNG_CALLOC(8 + ( 4 + 4 + 13 + 4) + // Signature + IHDR
  1223. (4 + 4 + palette.color_count*3 + 4) + // PLTE
  1224. (trns_required? (4 + 4 + palette.color_count + 4) : 0) + // tRNS
  1225. (4 + 4 + comp_data_size + 4) + 12, 1); // IDAT + IEND
  1226. // Write PNG signature
  1227. memcpy(output_buffer, png_signature, 8);
  1228. // Write PNG chunk IHDR
  1229. unsigned int length_IHDR = 13;
  1230. length_IHDR = swap_endian(length_IHDR);
  1231. memcpy(output_buffer + 8, &length_IHDR, 4);
  1232. memcpy(output_buffer + 8 + 4, "IHDR", 4);
  1233. memcpy(output_buffer + 8 + 8, &image_info, 13);
  1234. unsigned int crc = compute_crc32((unsigned char *)output_buffer + 8 + 4, 4 + 13);
  1235. crc = swap_endian(crc);
  1236. memcpy(output_buffer + 8 + 8 + 13, &crc, 4);
  1237. output_buffer_size += (8 + 12 + 13);
  1238. // Write PNG chunk PLTE (palette)
  1239. unsigned int length_PLTE = palette.color_count*3;
  1240. length_PLTE = swap_endian(length_PLTE);
  1241. memcpy(output_buffer + output_buffer_size, &length_PLTE, 4);
  1242. memcpy(output_buffer + output_buffer_size + 4, "PLTE", 4);
  1243. char *plte_data = (char *)RPNG_CALLOC(palette.color_count*3, sizeof(char));
  1244. for (int i = 0; i < palette.color_count; i++)
  1245. {
  1246. plte_data[i*3 + 0] = palette.colors[i].r;
  1247. plte_data[i*3 + 1] = palette.colors[i].g;
  1248. plte_data[i*3 + 2] = palette.colors[i].b;
  1249. }
  1250. memcpy(output_buffer + output_buffer_size + 8, plte_data, palette.color_count*3);
  1251. RPNG_FREE(plte_data);
  1252. crc = compute_crc32((unsigned char *)output_buffer + output_buffer_size + 4, 4 + palette.color_count*3);
  1253. crc = swap_endian(crc);
  1254. memcpy(output_buffer + output_buffer_size + 8 + palette.color_count*3, &crc, 4);
  1255. output_buffer_size += (palette.color_count*3 + 12);
  1256. // Write PNG chunk tRNS (palette alpha values, if required)
  1257. if (trns_required)
  1258. {
  1259. unsigned int length_tRNS = palette.color_count;
  1260. length_tRNS = swap_endian(length_tRNS);
  1261. memcpy(output_buffer + output_buffer_size, &length_tRNS, 4);
  1262. memcpy(output_buffer + output_buffer_size + 4, "tRNS", 4);
  1263. char *trns_data = (char *)RPNG_CALLOC(palette.color_count, sizeof(char));
  1264. for (int i = 0; i < palette.color_count; i++) trns_data[i] = palette.colors[i].a;
  1265. memcpy(output_buffer + output_buffer_size + 8, trns_data, palette.color_count);
  1266. RPNG_FREE(trns_data);
  1267. crc = compute_crc32((unsigned char *)output_buffer + output_buffer_size + 4, 4 + palette.color_count);
  1268. crc = swap_endian(crc);
  1269. memcpy(output_buffer + output_buffer_size + 8 + palette.color_count, &crc, 4);
  1270. output_buffer_size += (palette.color_count + 12);
  1271. }
  1272. // Write PNG chunk IDAT
  1273. unsigned int length_IDAT = comp_data_size;
  1274. length_IDAT = swap_endian(length_IDAT);
  1275. memcpy(output_buffer + output_buffer_size, &length_IDAT, 4);
  1276. memcpy(output_buffer + output_buffer_size + 4, "IDAT", 4);
  1277. memcpy(output_buffer + output_buffer_size + 8, comp_data, comp_data_size);
  1278. crc = compute_crc32((unsigned char *)output_buffer + output_buffer_size + 4, 4 + comp_data_size);
  1279. crc = swap_endian(crc);
  1280. memcpy(output_buffer + output_buffer_size + 8 + comp_data_size, &crc, 4);
  1281. output_buffer_size += (comp_data_size + 12);
  1282. // Write PNG chunk IEND
  1283. unsigned char chunk_IEND[12] = { 0, 0, 0, 0, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82 };
  1284. memcpy(output_buffer + output_buffer_size, chunk_IEND, 12);
  1285. output_buffer_size += 12;
  1286. }
  1287. RPNG_FREE(comp_data);
  1288. *output_size = output_buffer_size;
  1289. return output_buffer;
  1290. }
  1291. // Convert indexed image data to RGBA data
  1292. char *rpng_unindex_image_data(char *indexed_data, int width, int height, rpng_palette palette)
  1293. {
  1294. char *data = NULL;
  1295. if ((indexed_data != NULL) && (palette.color_count > 0) && (palette.colors != NULL))
  1296. {
  1297. data = (char *)RPNG_CALLOC(width*height*4, sizeof(char));
  1298. for (int i = 0; i < width*height; i++)
  1299. {
  1300. data[i*4 + 0] = palette.colors[(int)indexed_data[i]].r;
  1301. data[i*4 + 1] = palette.colors[(int)indexed_data[i]].g;
  1302. data[i*4 + 2] = palette.colors[(int)indexed_data[i]].b;
  1303. data[i*4 + 3] = palette.colors[(int)indexed_data[i]].a;
  1304. }
  1305. }
  1306. else RPNG_LOG("Provided indexed data or palette not valid, data can not be un-indexed\n");
  1307. return data;
  1308. }
  1309. //-------------------------------------------------------------------------------------------------
  1310. // PNG chunks managemeng functionality
  1311. //-------------------------------------------------------------------------------------------------
  1312. // Count the chunks in a PNG image from memory buffer
  1313. int rpng_chunk_count_from_memory(const char *buffer)
  1314. {
  1315. char *buffer_ptr = (char *)buffer;
  1316. int count = 0;
  1317. // NOTE: We check minimum file_size for a PNG (Signature + chunk IHDR + chunk IDAT + chunk IEND)
  1318. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1319. {
  1320. buffer_ptr += 8; // Move pointer after signature
  1321. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1322. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1323. {
  1324. buffer_ptr += (4 + 4 + chunk_size + 4); // Skip chunk Length + FOURCC + chunk data + CRC32
  1325. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1326. count++;
  1327. }
  1328. count++; // IEND chunk!
  1329. }
  1330. return count;
  1331. }
  1332. // Read one chunk type from memory buffer
  1333. rpng_chunk rpng_chunk_read_from_memory(const char *buffer, const char *chunk_type)
  1334. {
  1335. char *buffer_ptr = (char *)buffer;
  1336. rpng_chunk chunk = { 0 };
  1337. // NOTE: We check minimum file_size for a PNG (Signature + chunk IHDR + chunk IDAT + chunk IEND)
  1338. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1339. {
  1340. buffer_ptr += 8; // Move pointer after signature
  1341. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1342. // In case chunk(s) requested is IDAT, all IDAT chunks are concatenated
  1343. if (memcmp(chunk_type, "IDAT", 4) == 0)
  1344. {
  1345. char *idat_data_concat = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, sizeof(char));
  1346. int idat_data_concat_size = 0;
  1347. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1348. {
  1349. if (memcmp(buffer_ptr + 4, chunk_type, 4) == 0) // Check next IDAT chunk
  1350. {
  1351. memcpy(idat_data_concat + idat_data_concat_size, (char *)(buffer_ptr + 8), chunk_size);
  1352. idat_data_concat_size += chunk_size;
  1353. // TODO: Validate every IDAT chunk CRC32
  1354. }
  1355. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk of input data
  1356. chunk_size = swap_endian(((int *)buffer_ptr)[0]); // Compute next chunk file_size
  1357. }
  1358. // Fill chunk data with all accumulated IDAT
  1359. chunk.length = idat_data_concat_size;
  1360. memcpy(chunk.type, "IDAT", 4);
  1361. chunk.data = (char *)RPNG_CALLOC(idat_data_concat_size, sizeof(char));
  1362. memcpy(chunk.data, idat_data_concat, idat_data_concat_size);
  1363. RPNG_FREE(idat_data_concat);
  1364. // Compute CRC32 for security
  1365. unsigned char *chunk_type_data = (unsigned char *)RPNG_CALLOC(4 + chunk.length, 1);
  1366. memcpy(chunk_type_data, chunk.type, 4);
  1367. memcpy(chunk_type_data + 4, chunk.data, chunk.length);
  1368. chunk.crc = compute_crc32(chunk_type_data, 4 + chunk.length);
  1369. RPNG_FREE(chunk_type_data);
  1370. }
  1371. else // Only one chunk required, not IDAT type
  1372. {
  1373. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1374. {
  1375. if (memcmp(buffer_ptr + 4, chunk_type, 4) == 0)
  1376. {
  1377. chunk.length = chunk_size;
  1378. memcpy(chunk.type, (char *)(buffer_ptr + 4), 4);
  1379. chunk.data = (char *)RPNG_MALLOC(chunk_size);
  1380. memcpy(chunk.data, buffer_ptr + 8, chunk_size);
  1381. chunk.crc = swap_endian(((unsigned int *)(buffer_ptr + 8 + chunk_size))[0]);
  1382. break;
  1383. }
  1384. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk of input data
  1385. chunk_size = swap_endian(((int *)buffer_ptr)[0]); // Compute next chunk file_size
  1386. }
  1387. }
  1388. }
  1389. return chunk;
  1390. }
  1391. // Read all chunks from memory buffer
  1392. rpng_chunk *rpng_chunk_read_all_from_memory(const char *buffer, int *count)
  1393. {
  1394. char *buffer_ptr = (char *)buffer;
  1395. rpng_chunk *chunks = NULL;
  1396. int counter = 0;
  1397. // NOTE: We check minimum file_size for a PNG (Signature + chunk IHDR + chunk IDAT + chunk IEND)
  1398. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file signature
  1399. {
  1400. // We allocate enough space for 64 chunks
  1401. chunks = (rpng_chunk *)RPNG_CALLOC(RPNG_MAX_CHUNKS_COUNT, sizeof(rpng_chunk));
  1402. buffer_ptr += 8; // Move pointer after signature
  1403. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1404. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1405. {
  1406. chunks[counter].length = chunk_size;
  1407. memcpy(chunks[counter].type, (char *)(buffer_ptr + 4), 4);
  1408. chunks[counter].data = (char *)RPNG_MALLOC(chunk_size);
  1409. memcpy(chunks[counter].data, buffer_ptr + 8, chunk_size);
  1410. chunks[counter].crc = swap_endian(((unsigned int *)(buffer_ptr + 8 + chunk_size))[0]);
  1411. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk
  1412. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1413. counter++;
  1414. if (counter >= (RPNG_MAX_CHUNKS_COUNT - 2)) break; // WARNING: Too many chunks!
  1415. }
  1416. // Read final IEND chunk
  1417. chunks[counter].length = chunk_size;
  1418. memcpy(chunks[counter].type, (char *)(buffer_ptr + 4), 4);
  1419. chunks[counter].data = (char *)RPNG_MALLOC(chunk_size);
  1420. memcpy(chunks[counter].data, buffer_ptr + 8, chunk_size);
  1421. chunks[counter].crc = swap_endian(((unsigned int *)(buffer_ptr + 8 + chunk_size))[0]);
  1422. counter++;
  1423. // Reallocate chunks file_size
  1424. rpng_chunk *chunks_resized = (rpng_chunk*)RPNG_REALLOC(chunks, counter*sizeof(rpng_chunk));
  1425. if (chunks_resized != NULL) chunks = chunks_resized;
  1426. }
  1427. *count = counter;
  1428. return chunks;
  1429. }
  1430. // Remove one chunk type from memory buffer
  1431. // NOTE: returns output_data and output_size through parameter
  1432. char *rpng_chunk_remove_from_memory(const char *buffer, const char *chunk_type, int *output_size)
  1433. {
  1434. char *buffer_ptr = (char *)buffer;
  1435. char *output_buffer = NULL;
  1436. int output_buffer_size = 0;
  1437. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1438. {
  1439. output_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // Output buffer allocation
  1440. memcpy(output_buffer, png_signature, 8); // Copy PNG signature
  1441. output_buffer_size += 8;
  1442. buffer_ptr += 8; // Move pointer after signature
  1443. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1444. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1445. {
  1446. // If chunk type is not the requested, just copy input data into output buffer
  1447. if (memcmp(buffer_ptr + 4, chunk_type, 4) != 0)
  1448. {
  1449. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + chunk_size + 4); // Length + FOURCC + chunk_size + CRC32
  1450. output_buffer_size += (4 + 4 + chunk_size + 4);
  1451. }
  1452. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk
  1453. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1454. }
  1455. // Write IEND chunk
  1456. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + 4);
  1457. output_buffer_size += 12;
  1458. // Resize output buffer
  1459. char *output_buffer_sized = (char *)RPNG_REALLOC(output_buffer, output_buffer_size);
  1460. if (output_buffer_sized != NULL) output_buffer = output_buffer_sized;
  1461. }
  1462. *output_size = output_buffer_size;
  1463. return output_buffer;
  1464. }
  1465. // Remove all chunks from memory buffer except: IHDR-IDAT-IEND
  1466. // NOTE: returns output_data and output_size through parameter
  1467. char *rpng_chunk_remove_ancillary_from_memory(const char *buffer, int *output_size)
  1468. {
  1469. char *buffer_ptr = (char *)buffer;
  1470. char *output_buffer = NULL;
  1471. int output_buffer_size = 0;
  1472. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1473. {
  1474. bool preserve_palette_transparency = false;
  1475. output_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // Output buffer allocation
  1476. memcpy(output_buffer, png_signature, 8); // Copy PNG signature
  1477. output_buffer_size += 8;
  1478. buffer_ptr += 8; // Move pointer after signature
  1479. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1480. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1481. {
  1482. if (memcmp(buffer_ptr + 4, "PLTE", 4) == 0) preserve_palette_transparency = true;
  1483. // If chunk type is mandatory, just copy input data into output buffer
  1484. if ((memcmp(buffer_ptr + 4, "IHDR", 4) == 0) ||
  1485. (memcmp(buffer_ptr + 4, "PLTE", 4) == 0) ||
  1486. (memcmp(buffer_ptr + 4, "IDAT", 4) == 0) ||
  1487. (preserve_palette_transparency && (memcmp(buffer_ptr + 4, "tRNS", 4) == 0)))
  1488. {
  1489. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + chunk_size + 4); // Length + FOURCC + chunk_size + CRC32
  1490. output_buffer_size += (4 + 4 + chunk_size + 4);
  1491. }
  1492. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk
  1493. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1494. }
  1495. // Write IEND chunk
  1496. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + 4);
  1497. output_buffer_size += 12;
  1498. // Resize output buffer
  1499. char *output_buffer_sized = (char *)RPNG_REALLOC(output_buffer, output_buffer_size);
  1500. if (output_buffer_sized != NULL) output_buffer = output_buffer_sized;
  1501. }
  1502. *output_size = output_buffer_size;
  1503. return output_buffer;
  1504. }
  1505. // Write one new chunk after IHDR (any kind) to memory buffer
  1506. // NOTE: returns output data file_size
  1507. char *rpng_chunk_write_from_memory(const char *buffer, rpng_chunk chunk, int *output_size)
  1508. {
  1509. char *buffer_ptr = (char *)buffer;
  1510. char *output_buffer = NULL;
  1511. int output_buffer_size = 0;
  1512. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1513. {
  1514. output_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1);
  1515. memcpy(output_buffer, png_signature, 8); // Copy PNG signature
  1516. output_buffer_size += 8;
  1517. buffer_ptr += 8; // Move pointer after signature
  1518. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1519. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1520. {
  1521. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + chunk_size + 4); // Length + FOURCC + chunk_size + CRC32
  1522. output_buffer_size += (4 + 4 + chunk_size + 4);
  1523. // Check if we just copied the IHDR chunk to append our chunk after it
  1524. if (memcmp(buffer_ptr + 4, "IHDR", 4) == 0)
  1525. {
  1526. int chunk_length_be = swap_endian(chunk.length);
  1527. memcpy(output_buffer + output_buffer_size, &chunk_length_be, sizeof(int)); // Write chunk length
  1528. memcpy(output_buffer + output_buffer_size + 4, chunk.type, 4); // Write chunk type
  1529. memcpy(output_buffer + output_buffer_size + 4 + 4, chunk.data, chunk.length); // Write chunk data
  1530. unsigned char *type_data = (unsigned char *)RPNG_MALLOC(4 + chunk.length);
  1531. memcpy(type_data, chunk.type, 4);
  1532. memcpy(type_data + 4, chunk.data, chunk.length);
  1533. unsigned int crc = compute_crc32(type_data, 4 + chunk.length);
  1534. crc = swap_endian(crc);
  1535. memcpy(output_buffer + output_buffer_size + 4 + 4 + chunk.length, &crc, 4); // Write CRC32 (computed over type + data)
  1536. RPNG_FREE(type_data);
  1537. output_buffer_size += (4 + 4 + chunk.length + 4); // Update output file file_size with new chunk
  1538. }
  1539. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk of input data
  1540. chunk_size = swap_endian(((int *)buffer_ptr)[0]); // Compute next chunk file_size
  1541. }
  1542. // Write IEND chunk
  1543. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + 4);
  1544. output_buffer_size += 12;
  1545. // Resize output buffer
  1546. char *output_buffer_sized = (char *)RPNG_REALLOC(output_buffer, output_buffer_size);
  1547. if (output_buffer_sized != NULL) output_buffer = output_buffer_sized;
  1548. }
  1549. *output_size = output_buffer_size;
  1550. return output_buffer;
  1551. }
  1552. // Combine multiple IDAT chunks into a single one
  1553. // NOTE: Returns buffer with all concatenated IDAT chunks
  1554. char *rpng_chunk_combine_image_data_from_memory(char *buffer, int *output_size)
  1555. {
  1556. char *buffer_ptr = (char *)buffer;
  1557. char *output_buffer = NULL;
  1558. int output_buffer_size = 0;
  1559. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1560. {
  1561. char *idata_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // Output buffer allocation
  1562. memcpy(idata_buffer, "IDAT", 4);
  1563. int idata_buffer_size = 0;
  1564. output_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // Output buffer allocation
  1565. memcpy(output_buffer, png_signature, 8); // Copy PNG signature
  1566. output_buffer_size += 8;
  1567. buffer_ptr += 8; // Move pointer after signature
  1568. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1569. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1570. {
  1571. // If IDAT chunk just copy data into idata_buffer
  1572. if ((memcmp(buffer_ptr + 4, "IDAT", 4) == 0))
  1573. {
  1574. memcpy(idata_buffer + 4 + idata_buffer_size, buffer_ptr + 8, chunk_size);
  1575. idata_buffer_size += chunk_size;
  1576. }
  1577. else
  1578. {
  1579. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + chunk_size + 4); // Length + FOURCC + chunk_size + CRC32
  1580. output_buffer_size += (4 + 4 + chunk_size + 4);
  1581. }
  1582. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk
  1583. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1584. }
  1585. // Write IDAT combined chunk
  1586. unsigned int idata_buffer_size_be = swap_endian(idata_buffer_size);
  1587. memcpy(output_buffer + output_buffer_size, &idata_buffer_size_be, 4);
  1588. memcpy(output_buffer + output_buffer_size + 4, idata_buffer, 4 + idata_buffer_size);
  1589. unsigned int crc = compute_crc32((unsigned char *)idata_buffer, 4 + idata_buffer_size);
  1590. crc = swap_endian(crc);
  1591. memcpy(output_buffer + output_buffer_size + 4 + 4 + idata_buffer_size, &crc, 4);
  1592. RPNG_FREE(idata_buffer);
  1593. output_buffer_size += (idata_buffer_size + 12);
  1594. // Write IEND chunk
  1595. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + 4);
  1596. output_buffer_size += 12;
  1597. // Resize output buffer
  1598. char *output_buffer_sized = (char *)RPNG_REALLOC(output_buffer, output_buffer_size);
  1599. if (output_buffer_sized != NULL) output_buffer = output_buffer_sized;
  1600. }
  1601. *output_size = output_buffer_size;
  1602. return output_buffer;
  1603. }
  1604. // Split one IDAT chunk into multiple ones
  1605. char *rpng_chunk_split_image_data_from_memory(char *buffer, int split_size, int *output_size)
  1606. {
  1607. char *buffer_ptr = (char *)buffer;
  1608. char *output_buffer = NULL;
  1609. int output_buffer_size = 0;
  1610. if ((buffer_ptr != NULL) && (memcmp(buffer_ptr, png_signature, 8) == 0)) // Check valid PNG file
  1611. {
  1612. char *idata_split_buffer = (char *)RPNG_CALLOC(split_size + 12, 1); // Output buffer allocation
  1613. output_buffer = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // Output buffer allocation
  1614. memcpy(output_buffer, png_signature, 8); // Copy PNG signature
  1615. output_buffer_size += 8;
  1616. buffer_ptr += 8; // Move pointer after signature
  1617. unsigned int chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1618. while (memcmp(buffer_ptr + 4, "IEND", 4) != 0) // While IEND chunk not reached
  1619. {
  1620. // If IDAT chunk, split into multiple sized chunks
  1621. if ((memcmp(buffer_ptr + 4, "IDAT", 4) == 0) && (chunk_size > (unsigned int)split_size))
  1622. {
  1623. // Split chunk into pieces!
  1624. unsigned int chunk_remain_size = chunk_size;
  1625. char *buffer_ptr_offset = buffer_ptr + 4 + 4;
  1626. while (chunk_remain_size > (unsigned int)split_size)
  1627. {
  1628. unsigned int split_size_be = swap_endian(split_size);
  1629. memcpy(idata_split_buffer, &split_size_be, 4);
  1630. memcpy(idata_split_buffer + 4, "IDAT", 4);
  1631. memcpy(idata_split_buffer + 4 + 4, buffer_ptr_offset, split_size);
  1632. unsigned int crc = compute_crc32((unsigned char *)(idata_split_buffer + 4), 4 + split_size);
  1633. crc = swap_endian(crc);
  1634. memcpy(idata_split_buffer + 4 + 4 + split_size, &crc, 4);
  1635. chunk_remain_size -= split_size;
  1636. buffer_ptr_offset += split_size;
  1637. memcpy(output_buffer + output_buffer_size, idata_split_buffer, split_size + 12);
  1638. output_buffer_size += (split_size + 12);
  1639. }
  1640. // Save last IDAT chunk piece
  1641. unsigned int chunk_remain_size_be = swap_endian(chunk_remain_size);
  1642. memcpy(idata_split_buffer, &chunk_remain_size_be, 4);
  1643. memcpy(idata_split_buffer + 4, "IDAT", 4);
  1644. memcpy(idata_split_buffer + 4 + 4, buffer_ptr_offset, chunk_remain_size);
  1645. unsigned int crc = compute_crc32((unsigned char *)(idata_split_buffer + 4), 4 + chunk_remain_size);
  1646. crc = swap_endian(crc);
  1647. memcpy(idata_split_buffer + 4 + 4 + chunk_remain_size, &crc, 4);
  1648. memcpy(output_buffer + output_buffer_size, idata_split_buffer, chunk_remain_size + 12);
  1649. output_buffer_size += (chunk_remain_size + 12);
  1650. }
  1651. else
  1652. {
  1653. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + chunk_size + 4); // Length + FOURCC + chunk_size + CRC32
  1654. output_buffer_size += (4 + 4 + chunk_size + 4);
  1655. }
  1656. buffer_ptr += (4 + 4 + chunk_size + 4); // Move pointer to next chunk
  1657. chunk_size = swap_endian(((int *)buffer_ptr)[0]);
  1658. }
  1659. RPNG_FREE(idata_split_buffer);
  1660. // Write IEND chunk
  1661. memcpy(output_buffer + output_buffer_size, buffer_ptr, 4 + 4 + 4);
  1662. output_buffer_size += 12;
  1663. // Resize output buffer
  1664. char *output_buffer_sized = (char *)RPNG_REALLOC(output_buffer, output_buffer_size);
  1665. if (output_buffer_sized != NULL) output_buffer = output_buffer_sized;
  1666. }
  1667. *output_size = output_buffer_size;
  1668. return output_buffer;
  1669. }
  1670. //----------------------------------------------------------------------------------
  1671. // Module specific Functions Definition
  1672. //----------------------------------------------------------------------------------
  1673. // Prefilter and compress image data
  1674. static char *rpng_deflate_image_data(const char *image_data, int image_data_size, int width, int height, int pixel_size, int *output_size, int forced_filter_type)
  1675. {
  1676. char *idat_data = NULL;
  1677. // Image data pre-processing to append filter type byte to every scanline
  1678. //int pixel_size = color_channels*(bit_depth/8);
  1679. int scanline_size = width*pixel_size;
  1680. unsigned int data_filtered_size = (scanline_size + 1)*height; // Adding 1 byte per scanline filter
  1681. unsigned char *data_filtered = (unsigned char *)RPNG_CALLOC(data_filtered_size, 1);
  1682. int out = 0, x = 0, a = 0, b = 0, c = 0;
  1683. int sum_value[5] = { 0 };
  1684. int best_filter = 0;
  1685. for (int y = 0; y < height; y++)
  1686. {
  1687. if (forced_filter_type == -1)
  1688. {
  1689. // Choose the best filter type for every scanline
  1690. // REF: https://www.w3.org/TR/PNG-Encoders.html#E.Filter-selection
  1691. for (int p = 0; p < scanline_size; p++)
  1692. {
  1693. // x = current byte
  1694. // a = left pixel byte (from current)
  1695. // b = above pixel byte (from current)
  1696. // c = left pixel byte (from b)
  1697. x = (int)((unsigned char *)image_data)[scanline_size*y + p];
  1698. a = (p >= pixel_size) ? (int)((unsigned char *)image_data)[scanline_size*y + p - pixel_size] : 0;
  1699. b = (y > 0) ? (int)((unsigned char *)image_data)[scanline_size*(y - 1) + p] : 0;
  1700. c = (y > 0) ? ((p >= pixel_size) ? (int)((unsigned char *)image_data)[scanline_size*(y - 1) + p - pixel_size] : 0) : 0;
  1701. // Heuristic: Compute the output scanline using all five filters
  1702. // REF: https://www.w3.org/TR/PNG/#9Filters
  1703. for (int filter = 0; filter < 5; filter++)
  1704. {
  1705. switch (filter)
  1706. {
  1707. case 0: out = x; break;
  1708. case 1: out = x - a; break;
  1709. case 2: out = x - b; break;
  1710. case 3: out = x - ((a + b)>>1); break;
  1711. case 4: out = x - rpng_paeth_predictor(a, b, c); break;
  1712. default: break;
  1713. }
  1714. sum_value[filter] += abs((signed char)out);
  1715. }
  1716. }
  1717. // Select the filter that gives the smallest sum of absolute values of outputs.
  1718. // NOTE: Considering the output bytes as signed differences for the test.
  1719. best_filter = 0;
  1720. int best_value = sum_value[0];
  1721. for (int filter = 1; filter < 5; filter++)
  1722. {
  1723. if (sum_value[filter] < best_value)
  1724. {
  1725. best_value = sum_value[filter];
  1726. best_filter = filter;
  1727. }
  1728. }
  1729. }
  1730. else if ((forced_filter_type >= 0) && (forced_filter_type <= 4)) best_filter = forced_filter_type;
  1731. // Register scanline filter byte
  1732. data_filtered[(scanline_size + 1)*y] = best_filter;
  1733. // Apply the best_filter to scanline
  1734. for (int p = 0; p < scanline_size; p++)
  1735. {
  1736. x = (int)((unsigned char *)image_data)[scanline_size*y + p];
  1737. a = (p >= pixel_size)? (int)((unsigned char *)image_data)[scanline_size*y + p - pixel_size] : 0;
  1738. b = (y > 0)? (int)((unsigned char *)image_data)[scanline_size*(y - 1) + p] : 0;
  1739. c = (y > 0)? ((p >= pixel_size) ? (int)((unsigned char *)image_data)[scanline_size*(y - 1) + p - pixel_size] : 0) : 0;
  1740. switch (best_filter)
  1741. {
  1742. case 0: out = x; break;
  1743. case 1: out = x - a; break;
  1744. case 2: out = x - b; break;
  1745. case 3: out = x - ((a + b)>>1); break;
  1746. case 4: out = x - rpng_paeth_predictor(a, b, c); break;
  1747. default: break;
  1748. }
  1749. // Register scanline filtered values, byte by byte
  1750. data_filtered[(scanline_size + 1)*y + 1 + p] = (unsigned char)out;
  1751. }
  1752. }
  1753. // Compress filtered image data and generate a valid zlib stream
  1754. struct sdefl *sde = (struct sdefl*)RPNG_CALLOC(sizeof(struct sdefl), 1);
  1755. int bounds = sdefl_bound(data_filtered_size);
  1756. char *comp_data = (char *)RPNG_CALLOC(bounds, 1);
  1757. int comp_data_size = zsdeflate(sde, comp_data, data_filtered, data_filtered_size, RPNG_COMPRESSION_LEVEL);
  1758. RPNG_FREE(data_filtered);
  1759. RPNG_FREE(sde);
  1760. if ((comp_data != NULL) && (comp_data_size > 0))
  1761. {
  1762. idat_data = comp_data;
  1763. *output_size = comp_data_size;
  1764. RPNG_LOG("INFO: Image data deflated successfully: %i bytes -> %i bytes\n", data_filtered_size, comp_data_size);
  1765. }
  1766. else RPNG_LOG("INFO: Image data deflating failed\n");
  1767. return idat_data;
  1768. }
  1769. // Decompress and unfilter image data (IDAT)
  1770. static char *rpng_inflate_image_data(char *image_data, int image_data_size, int width, int height, int pixel_size)
  1771. {
  1772. char *image_data_unfiltered = NULL;
  1773. char *image_data_filtered = (char *)RPNG_CALLOC(RPNG_MAX_OUTPUT_SIZE, 1); // WARNING: Allocate enough memory to load full image decompressed
  1774. // Decompress IDAT chunk data
  1775. int image_data_decomp_size = zsinflate(image_data_filtered, RPNG_MAX_OUTPUT_SIZE, image_data, image_data_size);
  1776. RPNG_LOG("INFO: IDAT data decompressed: %i -> %i\n", image_data_size, image_data_decomp_size);
  1777. if ((image_data_filtered != NULL) && (image_data_decomp_size > 0))
  1778. {
  1779. // Now we have the data decompressed but every scanline of the image was originally filtered for
  1780. // maximum compression and one extra byte with the filter type was added to every scanline
  1781. // We must undo that image prefiltering for every scanline
  1782. // Image data reverse pre-processing for filter type
  1783. //int pixel_size = *color_channels*(*bit_depth/8);
  1784. int scanline_size = width*pixel_size;
  1785. image_data_unfiltered = (char *)RPNG_CALLOC(image_data_decomp_size, 1); // Actually data unfiltered size should be smaller
  1786. int current_filter = 0;
  1787. int out = 0, x = 0, a = 0, b = 0, c = 0;
  1788. // Reverse scanlines filters
  1789. for (int y = 0; y < height; y++) // Move scanline by scanline, we must discard first byte = current_filter
  1790. {
  1791. current_filter = (int)image_data_filtered[(1 + scanline_size)*y];
  1792. for (int p = 0; p < scanline_size; p++)
  1793. {
  1794. // x = current byte
  1795. // a = left pixel byte (from current)
  1796. // b = above pixel byte (from current)
  1797. // c = left pixel byte (from b)
  1798. x = (int)(image_data_filtered[(1 + scanline_size)*y + 1 + p]);
  1799. a = (p >= pixel_size) ? (int)(image_data_unfiltered[scanline_size*y + p - pixel_size]) : 0;
  1800. b = (y > 0) ? (int)(image_data_unfiltered[scanline_size*(y - 1) + p]) : 0;
  1801. c = (y > 0) ? ((p >= pixel_size) ? (int)(image_data_unfiltered[scanline_size*(y - 1) + p - pixel_size]) : 0) : 0;
  1802. switch (current_filter)
  1803. {
  1804. case 0: out = x; break; // Filter type 0: None (Usually used for indexed images)
  1805. case 1: out = x + a; break; // Filter type 1: Sub
  1806. case 2: out = x + b; break; // Filter type 2: Up
  1807. case 3: out = x + ((a + b)>>1); break; // Filter type 3: Average
  1808. case 4: out = x + rpng_paeth_predictor(a, b, c); break; // Filter type 4: Paeth
  1809. default: break;
  1810. }
  1811. // Register scanline unfiltered values, byte by byte
  1812. image_data_unfiltered[y*scanline_size + p] = (char)out;
  1813. }
  1814. }
  1815. RPNG_FREE(image_data_filtered);
  1816. }
  1817. return image_data_unfiltered;
  1818. }
  1819. // Swap integer from big<->little endian
  1820. static unsigned int swap_endian(unsigned int value)
  1821. {
  1822. // Swap endian (big to little) or (little to big)
  1823. unsigned int b0, b1, b2, b3;
  1824. unsigned int res;
  1825. b0 = (value & 0x000000ff) << 24u;
  1826. b1 = (value & 0x0000ff00) << 8u;
  1827. b2 = (value & 0x00ff0000) >> 8u;
  1828. b3 = (value & 0xff000000) >> 24u;
  1829. res = b0 | b1 | b2 | b3;
  1830. return res;
  1831. }
  1832. // Compute CRC32
  1833. static unsigned int compute_crc32(unsigned char *buffer, int size)
  1834. {
  1835. static unsigned int crc_table[256] = {
  1836. 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
  1837. 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
  1838. 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  1839. 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
  1840. 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
  1841. 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  1842. 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
  1843. 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
  1844. 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  1845. 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
  1846. 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
  1847. 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  1848. 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
  1849. 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
  1850. 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  1851. 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
  1852. 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
  1853. 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  1854. 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
  1855. 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
  1856. 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  1857. 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
  1858. 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
  1859. 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  1860. 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
  1861. 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
  1862. 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  1863. 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
  1864. 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
  1865. 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  1866. 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
  1867. 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
  1868. };
  1869. unsigned int crc = ~0u;
  1870. for (int i = 0; i < size; i++) crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
  1871. return ~crc;
  1872. }
  1873. // Load data from file into a buffer
  1874. static char *load_file_to_buffer(const char *filename, int *bytes_read)
  1875. {
  1876. char *data = NULL;
  1877. *bytes_read = 0;
  1878. #if !defined(RPNG_NO_STDIO)
  1879. // Check if the file exists before reading it
  1880. if ((filename != NULL) && file_exists(filename))
  1881. {
  1882. FILE *file = fopen(filename, "rb");
  1883. if (file != NULL)
  1884. {
  1885. // WARNING: On binary streams SEEK_END could not be found,
  1886. // using fseek() and ftell() could not work in some (rare) cases
  1887. fseek(file, 0, SEEK_END);
  1888. int file_size = ftell(file);
  1889. fseek(file, 0, SEEK_SET);
  1890. if (file_size > 0)
  1891. {
  1892. data = (char *)RPNG_MALLOC(sizeof(unsigned char)*file_size);
  1893. // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, file_size elements]
  1894. int count = (int)fread(data, sizeof(char), file_size, file);
  1895. *bytes_read = count;
  1896. if (count != file_size) RPNG_LOG("FILEIO: [%s] File partially loaded\n", filename);
  1897. else RPNG_LOG("FILEIO: [%s] File loaded successfully\n", filename);
  1898. }
  1899. else RPNG_LOG("FILEIO: [%s] Failed to read file\n", filename);
  1900. fclose(file);
  1901. }
  1902. else RPNG_LOG("FILEIO: [%s] Failed to open file\n", filename);
  1903. }
  1904. else RPNG_LOG("FILEIO: File path provided is not valid\n");
  1905. #else
  1906. (void)filename;
  1907. #ifndef RPNG_NO_STDIO_WARNING
  1908. #warning No FILE I/O API, RPNG_NO_STDIO defined
  1909. #endif
  1910. #endif
  1911. return data;
  1912. }
  1913. // Write data to file from buffer
  1914. static int save_file_from_buffer(const char *filename, void *data, int bytesToWrite)
  1915. {
  1916. int result = RPNG_SUCCESS;
  1917. #if !defined(RPNG_NO_STDIO)
  1918. if ((filename != NULL) && (data != NULL) && (bytesToWrite > 0))
  1919. {
  1920. FILE *file = fopen(filename, "wb");
  1921. if (file != NULL)
  1922. {
  1923. int count = (int)fwrite(data, sizeof(char), bytesToWrite, file);
  1924. if (count == 0) RPNG_LOG("FILEIO: [%s] Failed to write file\n", filename);
  1925. else if (count != bytesToWrite) RPNG_LOG("FILEIO: [%s] File partially written\n", filename);
  1926. else RPNG_LOG("FILEIO: [%s] File saved successfully\n", filename);
  1927. fclose(file);
  1928. }
  1929. else
  1930. {
  1931. result = RPNG_ERROR_FILE_OPEN;
  1932. RPNG_LOG("FILEIO: [%s] Failed to open file\n", filename);
  1933. }
  1934. }
  1935. else RPNG_LOG("FILEIO: File path or data provided are not valid\n");
  1936. #else
  1937. (void)filename;
  1938. (void)data;
  1939. (void)bytesToWrite;
  1940. #ifndef RPNG_NO_STDIO_WARNING
  1941. #warning No FILE I/O API, RPNG_NO_STDIO defined
  1942. #endif
  1943. #endif
  1944. return result;
  1945. }
  1946. // Check if the file exists
  1947. static bool file_exists(const char *filename)
  1948. {
  1949. bool result = false;
  1950. #if defined(_WIN32)
  1951. if (_access(filename, 0) != -1) result = true;
  1952. #else
  1953. if (access(filename, F_OK) != -1) result = true;
  1954. #endif
  1955. return result;
  1956. }
  1957. #define RPNG_DEFLATE_IMPLEMENTATION
  1958. #if defined(RPNG_DEFLATE_IMPLEMENTATION)
  1959. //=========================================================================
  1960. // SDEFL
  1961. // DEFLATE COMPRESSION algorithm: https://github.com/vurtun/lib/sdefl.h
  1962. //=========================================================================
  1963. #ifdef SDEFL_IMPLEMENTATION
  1964. #include <assert.h> /* assert */
  1965. #include <string.h> /* memcpy */
  1966. #include <limits.h> /* CHAR_BIT */
  1967. #define SDEFL_NIL (-1)
  1968. #define SDEFL_MAX_MATCH 258
  1969. #define SDEFL_MAX_CODE_LEN (15)
  1970. #define SDEFL_SYM_BITS (10u)
  1971. #define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
  1972. #define SDEFL_RAW_BLK_SIZE (65535)
  1973. #define SDEFL_LIT_LEN_CODES (14)
  1974. #define SDEFL_OFF_CODES (15)
  1975. #define SDEFL_PRE_CODES (7)
  1976. #define SDEFL_CNT_NUM(n) ((((n)+3u/4u)+3u)&~3u)
  1977. #define SDEFL_EOB (256)
  1978. #define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
  1979. #define sdefl_div_round_up(n,d) (((n)+((d)-1))/(d))
  1980. static int
  1981. sdefl_ilog2(int n) {
  1982. if (!n) return 0;
  1983. #ifdef _MSC_VER
  1984. unsigned long msbp = 0;
  1985. _BitScanReverse(&msbp, (unsigned long)n);
  1986. return (int)msbp;
  1987. #elif defined(__GNUC__) || defined(__clang__)
  1988. return (int)sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl((unsigned long)n);
  1989. #else
  1990. #define lt(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
  1991. static const char tbl[256] = {
  1992. 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4), lt(5), lt(5), lt(6), lt(6), lt(6), lt(6),
  1993. lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7)};
  1994. int tt, t;
  1995. if ((tt = (n >> 16))) {
  1996. return (t = (tt >> 8)) ? 24 + tbl[t] : 16 + tbl[tt];
  1997. } else {
  1998. return (t = (n >> 8)) ? 8 + tbl[t] : tbl[n];
  1999. }
  2000. #undef lt
  2001. #endif
  2002. }
  2003. static unsigned
  2004. sdefl_uload32(const void *p) {
  2005. /* hopefully will be optimized to an unaligned read */
  2006. unsigned n = 0;
  2007. memcpy(&n, p, sizeof(n));
  2008. return n;
  2009. }
  2010. static unsigned
  2011. sdefl_hash32(const void *p) {
  2012. unsigned n = sdefl_uload32(p);
  2013. return (n * 0x9E377989) >> (32 - SDEFL_HASH_BITS);
  2014. }
  2015. static void
  2016. sdefl_put(unsigned char **dst, struct sdefl *s, int code, int bitcnt) {
  2017. s->bits |= (code << s->bitcnt);
  2018. s->bitcnt += bitcnt;
  2019. while (s->bitcnt >= 8) {
  2020. unsigned char *tar = *dst;
  2021. *tar = (unsigned char)(s->bits & 0xFF);
  2022. s->bits >>= 8;
  2023. s->bitcnt -= 8;
  2024. *dst = *dst + 1;
  2025. }
  2026. }
  2027. static void
  2028. sdefl_heap_sub(unsigned A[], unsigned len, unsigned sub) {
  2029. unsigned c, p = sub;
  2030. unsigned v = A[sub];
  2031. while ((c = p << 1) <= len) {
  2032. if (c < len && A[c + 1] > A[c]) c++;
  2033. if (v >= A[c]) break;
  2034. A[p] = A[c], p = c;
  2035. }
  2036. A[p] = v;
  2037. }
  2038. static void
  2039. sdefl_heap_array(unsigned *A, unsigned len) {
  2040. unsigned sub;
  2041. for (sub = len >> 1; sub >= 1; sub--)
  2042. sdefl_heap_sub(A, len, sub);
  2043. }
  2044. static void
  2045. sdefl_heap_sort(unsigned *A, unsigned n) {
  2046. A--;
  2047. sdefl_heap_array(A, n);
  2048. while (n >= 2) {
  2049. unsigned tmp = A[n];
  2050. A[n--] = A[1];
  2051. A[1] = tmp;
  2052. sdefl_heap_sub(A, n, 1);
  2053. }
  2054. }
  2055. static unsigned
  2056. sdefl_sort_sym(unsigned sym_cnt, unsigned *freqs,
  2057. unsigned char *lens, unsigned *sym_out) {
  2058. unsigned cnts[SDEFL_CNT_NUM(SDEFL_SYM_MAX)] = {0};
  2059. unsigned cnt_num = SDEFL_CNT_NUM(sym_cnt);
  2060. unsigned used_sym = 0;
  2061. unsigned sym, i;
  2062. for (sym = 0; sym < sym_cnt; sym++)
  2063. cnts[freqs[sym] < cnt_num-1 ? freqs[sym]: cnt_num-1]++;
  2064. for (i = 1; i < cnt_num; i++) {
  2065. unsigned cnt = cnts[i];
  2066. cnts[i] = used_sym;
  2067. used_sym += cnt;
  2068. }
  2069. for (sym = 0; sym < sym_cnt; sym++) {
  2070. unsigned freq = freqs[sym];
  2071. if (freq) {
  2072. unsigned idx = freq < cnt_num-1 ? freq : cnt_num-1;
  2073. sym_out[cnts[idx]++] = sym | (freq << SDEFL_SYM_BITS);
  2074. } else lens[sym] = 0;
  2075. }
  2076. sdefl_heap_sort(sym_out + cnts[cnt_num-2], cnts[cnt_num-1] - cnts[cnt_num-2]);
  2077. return used_sym;
  2078. }
  2079. static void
  2080. sdefl_build_tree(unsigned *A, unsigned sym_cnt) {
  2081. unsigned i = 0, b = 0, e = 0;
  2082. do {
  2083. unsigned m, n, freq_shift;
  2084. if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
  2085. m = i++;
  2086. else m = b++;
  2087. if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
  2088. n = i++;
  2089. else n = b++;
  2090. freq_shift = (A[m] & ~SDEFL_SYM_MSK) + (A[n] & ~SDEFL_SYM_MSK);
  2091. A[m] = (A[m] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
  2092. A[n] = (A[n] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
  2093. A[e] = (A[e] & SDEFL_SYM_MSK) | freq_shift;
  2094. } while (sym_cnt - ++e > 1);
  2095. }
  2096. static void
  2097. sdefl_gen_len_cnt(unsigned *A, unsigned root, unsigned *len_cnt,
  2098. unsigned max_code_len) {
  2099. int n;
  2100. unsigned i;
  2101. for (i = 0; i <= max_code_len; i++)
  2102. len_cnt[i] = 0;
  2103. len_cnt[1] = 2;
  2104. A[root] &= SDEFL_SYM_MSK;
  2105. for (n = (int)root - 1; n >= 0; n--) {
  2106. unsigned p = A[n] >> SDEFL_SYM_BITS;
  2107. unsigned pdepth = A[p] >> SDEFL_SYM_BITS;
  2108. unsigned depth = pdepth + 1;
  2109. unsigned len = depth;
  2110. A[n] = (A[n] & SDEFL_SYM_MSK) | (depth << SDEFL_SYM_BITS);
  2111. if (len >= max_code_len) {
  2112. len = max_code_len;
  2113. do len--; while (!len_cnt[len]);
  2114. }
  2115. len_cnt[len]--;
  2116. len_cnt[len+1] += 2;
  2117. }
  2118. }
  2119. static void
  2120. sdefl_gen_codes(unsigned *A, unsigned char *lens, const unsigned *len_cnt,
  2121. unsigned max_code_word_len, unsigned sym_cnt) {
  2122. unsigned i, sym, len, nxt[SDEFL_MAX_CODE_LEN + 1];
  2123. for (i = 0, len = max_code_word_len; len >= 1; len--) {
  2124. unsigned cnt = len_cnt[len];
  2125. while (cnt--) lens[A[i++] & SDEFL_SYM_MSK] = (unsigned char)len;
  2126. }
  2127. nxt[0] = nxt[1] = 0;
  2128. for (len = 2; len <= max_code_word_len; len++)
  2129. nxt[len] = (nxt[len-1] + len_cnt[len-1]) << 1;
  2130. for (sym = 0; sym < sym_cnt; sym++)
  2131. A[sym] = nxt[lens[sym]]++;
  2132. }
  2133. static unsigned
  2134. sdefl_rev(unsigned c, unsigned char n) {
  2135. c = ((c & 0x5555) << 1) | ((c & 0xAAAA) >> 1);
  2136. c = ((c & 0x3333) << 2) | ((c & 0xCCCC) >> 2);
  2137. c = ((c & 0x0F0F) << 4) | ((c & 0xF0F0) >> 4);
  2138. c = ((c & 0x00FF) << 8) | ((c & 0xFF00) >> 8);
  2139. return c >> (16-n);
  2140. }
  2141. static void
  2142. sdefl_huff(unsigned char *lens, unsigned *codes, unsigned *freqs,
  2143. unsigned num_syms, unsigned max_code_len) {
  2144. unsigned c, *A = codes;
  2145. unsigned len_cnt[SDEFL_MAX_CODE_LEN + 1];
  2146. unsigned used_syms = sdefl_sort_sym(num_syms, freqs, lens, A);
  2147. if (!used_syms) return;
  2148. if (used_syms == 1) {
  2149. unsigned s = A[0] & SDEFL_SYM_MSK;
  2150. unsigned i = s ? s : 1;
  2151. codes[0] = 0, lens[0] = 1;
  2152. codes[i] = 1, lens[i] = 1;
  2153. return;
  2154. }
  2155. sdefl_build_tree(A, used_syms);
  2156. sdefl_gen_len_cnt(A, used_syms-2, len_cnt, max_code_len);
  2157. sdefl_gen_codes(A, lens, len_cnt, max_code_len, num_syms);
  2158. for (c = 0; c < num_syms; c++) {
  2159. codes[c] = sdefl_rev(codes[c], lens[c]);
  2160. }
  2161. }
  2162. struct sdefl_symcnt {
  2163. int items;
  2164. int lit;
  2165. int off;
  2166. };
  2167. static void
  2168. sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
  2169. const unsigned char *litlen, const unsigned char *offlen) {
  2170. unsigned *at = items;
  2171. unsigned run_start = 0;
  2172. unsigned total = 0;
  2173. unsigned char lens[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
  2174. for (cnt->lit = SDEFL_SYM_MAX; cnt->lit > 257; cnt->lit--)
  2175. if (litlen[cnt->lit - 1]) break;
  2176. for (cnt->off = SDEFL_OFF_MAX; cnt->off > 1; cnt->off--)
  2177. if (offlen[cnt->off - 1]) break;
  2178. total = (unsigned)(cnt->lit + cnt->off);
  2179. memcpy(lens, litlen, sizeof(unsigned char) * (size_t)cnt->lit);
  2180. memcpy(lens + cnt->lit, offlen, sizeof(unsigned char) * (size_t)cnt->off);
  2181. do {
  2182. unsigned len = lens[run_start];
  2183. unsigned run_end = run_start;
  2184. do run_end++; while (run_end != total && len == lens[run_end]);
  2185. if (!len) {
  2186. while ((run_end - run_start) >= 11) {
  2187. unsigned n = (run_end - run_start) - 11;
  2188. unsigned xbits = n < 0x7f ? n : 0x7f;
  2189. freqs[18]++;
  2190. *at++ = 18u | (xbits << 5u);
  2191. run_start += 11 + xbits;
  2192. }
  2193. if ((run_end - run_start) >= 3) {
  2194. unsigned n = (run_end - run_start) - 3;
  2195. unsigned xbits = n < 0x7 ? n : 0x7;
  2196. freqs[17]++;
  2197. *at++ = 17u | (xbits << 5u);
  2198. run_start += 3 + xbits;
  2199. }
  2200. } else if ((run_end - run_start) >= 4) {
  2201. freqs[len]++;
  2202. *at++ = len;
  2203. run_start++;
  2204. do {
  2205. unsigned xbits = (run_end - run_start) - 3;
  2206. xbits = xbits < 0x03 ? xbits : 0x03;
  2207. *at++ = 16 | (xbits << 5);
  2208. run_start += 3 + xbits;
  2209. freqs[16]++;
  2210. } while ((run_end - run_start) >= 3);
  2211. }
  2212. while (run_start != run_end) {
  2213. freqs[len]++;
  2214. *at++ = len;
  2215. run_start++;
  2216. }
  2217. } while (run_start != total);
  2218. cnt->items = (int)(at - items);
  2219. }
  2220. struct sdefl_match_codest {
  2221. int ls, lc;
  2222. int dc, dx;
  2223. };
  2224. static void
  2225. sdefl_match_codes(struct sdefl_match_codest *cod, int dist, int len) {
  2226. static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
  2227. static const unsigned char lslot[258+1] = {
  2228. 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
  2229. 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,
  2230. 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,
  2231. 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
  2232. 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
  2233. 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
  2234. 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
  2235. 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
  2236. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
  2237. 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
  2238. 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
  2239. 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
  2240. 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
  2241. 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
  2242. 27, 27, 28
  2243. };
  2244. assert(len <= 258);
  2245. assert(dist <= 32768);
  2246. cod->ls = lslot[len];
  2247. cod->lc = 257 + cod->ls;
  2248. assert(cod->lc <= 285);
  2249. cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
  2250. cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
  2251. }
  2252. enum sdefl_blk_type {
  2253. SDEFL_BLK_UCOMPR,
  2254. SDEFL_BLK_DYN
  2255. };
  2256. static enum sdefl_blk_type
  2257. sdefl_blk_type(const struct sdefl *s, int blk_len, int pre_item_len,
  2258. const unsigned *pre_freq, const unsigned char *pre_len) {
  2259. static const unsigned char x_pre_bits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
  2260. static const unsigned char x_len_bits[] = {0,0,0,0,0,0,0,0, 1,1,1,1,2,2,2,2,
  2261. 3,3,3,3,4,4,4,4, 5,5,5,5,0};
  2262. static const unsigned char x_off_bits[] = {0,0,0,0,1,1,2,2, 3,3,4,4,5,5,6,6,
  2263. 7,7,8,8,9,9,10,10, 11,11,12,12,13,13};
  2264. int dyn_cost = 0;
  2265. int fix_cost = 0;
  2266. int sym = 0;
  2267. dyn_cost += 5 + 5 + 4 + (3 * pre_item_len);
  2268. for (sym = 0; sym < SDEFL_PRE_MAX; sym++)
  2269. dyn_cost += pre_freq[sym] * (x_pre_bits[sym] + pre_len[sym]);
  2270. for (sym = 0; sym < 256; sym++)
  2271. dyn_cost += s->freq.lit[sym] * s->cod.len.lit[sym];
  2272. dyn_cost += s->cod.len.lit[SDEFL_EOB];
  2273. for (sym = 257; sym < 286; sym++)
  2274. dyn_cost += s->freq.lit[sym] * (x_len_bits[sym - 257] + s->cod.len.lit[sym]);
  2275. for (sym = 0; sym < 30; sym++)
  2276. dyn_cost += s->freq.off[sym] * (x_off_bits[sym] + s->cod.len.off[sym]);
  2277. fix_cost += 8*(5 * sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE) + blk_len + 1 + 2);
  2278. return (dyn_cost < fix_cost) ? SDEFL_BLK_DYN : SDEFL_BLK_UCOMPR;
  2279. }
  2280. static void
  2281. sdefl_put16(unsigned char **dst, unsigned short x) {
  2282. unsigned char *val = *dst;
  2283. val[0] = (unsigned char)(x & 0xff);
  2284. val[1] = (unsigned char)(x >> 8);
  2285. *dst = val + 2;
  2286. }
  2287. static void
  2288. sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
  2289. static const char lxn[] = {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};
  2290. static const short lmin[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,
  2291. 51,59,67,83,99,115,131,163,195,227,258};
  2292. static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
  2293. 385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
  2294. struct sdefl_match_codest cod;
  2295. sdefl_match_codes(&cod, dist, len);
  2296. sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
  2297. sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
  2298. sdefl_put(dst, s, (int)s->cod.word.off[cod.dc], s->cod.len.off[cod.dc]);
  2299. sdefl_put(dst, s, dist - dmin[cod.dc], cod.dx);
  2300. }
  2301. static void
  2302. sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
  2303. const unsigned char *in, int blk_begin, int blk_end) {
  2304. int blk_len = blk_end - blk_begin;
  2305. int j, i = 0, item_cnt = 0;
  2306. struct sdefl_symcnt symcnt = {0};
  2307. unsigned codes[SDEFL_PRE_MAX];
  2308. unsigned char lens[SDEFL_PRE_MAX];
  2309. unsigned freqs[SDEFL_PRE_MAX] = {0};
  2310. unsigned items[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
  2311. static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
  2312. 4,12,3,13,2,14,1,15};
  2313. /* calculate huffman codes */
  2314. s->freq.lit[SDEFL_EOB]++;
  2315. sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
  2316. sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
  2317. sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
  2318. sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
  2319. for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
  2320. if (lens[perm[item_cnt - 1]]){
  2321. break;
  2322. }
  2323. }
  2324. /* write block */
  2325. switch (sdefl_blk_type(s, blk_len, item_cnt, freqs, lens)) {
  2326. case SDEFL_BLK_UCOMPR: {
  2327. /* uncompressed blocks */
  2328. int n = sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE);
  2329. for (i = 0; i < n; ++i) {
  2330. int fin = is_last && (i + 1 == n);
  2331. int amount = blk_len < SDEFL_RAW_BLK_SIZE ? blk_len : SDEFL_RAW_BLK_SIZE;
  2332. sdefl_put(dst, s, !!fin, 1); /* block */
  2333. sdefl_put(dst, s, 0x00, 2); /* stored block */
  2334. if (s->bitcnt) {
  2335. sdefl_put(dst, s, 0x00, 8 - s->bitcnt);
  2336. }
  2337. assert(s->bitcnt == 0);
  2338. sdefl_put16(dst, (unsigned short)amount);
  2339. sdefl_put16(dst, ~(unsigned short)amount);
  2340. memcpy(*dst, in + blk_begin + i * SDEFL_RAW_BLK_SIZE, amount);
  2341. *dst = *dst + amount;
  2342. blk_len -= amount;
  2343. }
  2344. } break;
  2345. case SDEFL_BLK_DYN: {
  2346. /* dynamic huffman block */
  2347. sdefl_put(dst, s, !!is_last, 1); /* block */
  2348. sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
  2349. sdefl_put(dst, s, symcnt.lit - 257, 5);
  2350. sdefl_put(dst, s, symcnt.off - 1, 5);
  2351. sdefl_put(dst, s, item_cnt - 4, 4);
  2352. for (i = 0; i < item_cnt; ++i) {
  2353. sdefl_put(dst, s, lens[perm[i]], 3);
  2354. }
  2355. for (i = 0; i < symcnt.items; ++i) {
  2356. unsigned sym = items[i] & 0x1F;
  2357. sdefl_put(dst, s, (int)codes[sym], lens[sym]);
  2358. if (sym < 16) continue;
  2359. if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
  2360. else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
  2361. else sdefl_put(dst, s, items[i] >> 5, 7);
  2362. }
  2363. /* block sequences */
  2364. for (i = 0; i < s->seq_cnt; ++i) {
  2365. if (s->seq[i].off >= 0) {
  2366. for (j = 0; j < s->seq[i].len; ++j) {
  2367. int c = in[s->seq[i].off + j];
  2368. sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
  2369. }
  2370. } else {
  2371. sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
  2372. }
  2373. }
  2374. sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
  2375. } break;}
  2376. memset(&s->freq, 0, sizeof(s->freq));
  2377. s->seq_cnt = 0;
  2378. }
  2379. static void
  2380. sdefl_seq(struct sdefl *s, int off, int len) {
  2381. assert(s->seq_cnt + 2 < SDEFL_SEQ_SIZ);
  2382. s->seq[s->seq_cnt].off = off;
  2383. s->seq[s->seq_cnt].len = len;
  2384. s->seq_cnt++;
  2385. }
  2386. static void
  2387. sdefl_reg_match(struct sdefl *s, int off, int len) {
  2388. struct sdefl_match_codest cod;
  2389. sdefl_match_codes(&cod, off, len);
  2390. assert(cod.lc < SDEFL_SYM_MAX);
  2391. assert(cod.dc < SDEFL_OFF_MAX);
  2392. s->freq.lit[cod.lc]++;
  2393. s->freq.off[cod.dc]++;
  2394. }
  2395. struct sdefl_match {
  2396. int off;
  2397. int len;
  2398. };
  2399. static void
  2400. sdefl_fnd(struct sdefl_match *m, const struct sdefl *s, int chain_len,
  2401. int max_match, const unsigned char *in, int p, int e) {
  2402. int i = s->tbl[sdefl_hash32(in + p)];
  2403. int limit = ((p - SDEFL_WIN_SIZ) < SDEFL_NIL) ? SDEFL_NIL : (p-SDEFL_WIN_SIZ);
  2404. assert(p < e);
  2405. assert(p + max_match <= e);
  2406. while (i > limit) {
  2407. assert(i + m->len < e);
  2408. assert(p + m->len < e);
  2409. assert(i + SDEFL_MIN_MATCH < e);
  2410. assert(p + SDEFL_MIN_MATCH < e);
  2411. if (in[i + m->len] == in[p + m->len] &&
  2412. (sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))) {
  2413. int n = SDEFL_MIN_MATCH;
  2414. while (n < max_match && in[i + n] == in[p + n]) {
  2415. assert(i + n < e);
  2416. assert(p + n < e);
  2417. n++;
  2418. }
  2419. if (n > m->len) {
  2420. m->len = n, m->off = p - i;
  2421. if (n == max_match)
  2422. break;
  2423. }
  2424. }
  2425. if (!(--chain_len)) break;
  2426. i = s->prv[i & SDEFL_WIN_MSK];
  2427. }
  2428. }
  2429. static int
  2430. sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
  2431. int in_len, int lvl) {
  2432. unsigned char *q = out;
  2433. static const unsigned char pref[] = {8,10,14,24,30,48,65,96,130};
  2434. int max_chain = (lvl < 8) ? (1 << (lvl + 1)): (1 << 13);
  2435. int n, i = 0, litlen = 0;
  2436. for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
  2437. s->tbl[n] = SDEFL_NIL;
  2438. }
  2439. do {int blk_begin = i;
  2440. int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
  2441. while (i < blk_end) {
  2442. struct sdefl_match m = {0};
  2443. int left = blk_end - i;
  2444. int max_match = (left > SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
  2445. int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
  2446. int run = 1, inc = 1, run_inc = 0;
  2447. if (max_match > SDEFL_MIN_MATCH) {
  2448. sdefl_fnd(&m, s, max_chain, max_match, in, i, in_len);
  2449. }
  2450. if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len + 1 < nice_match){
  2451. struct sdefl_match m2 = {0};
  2452. sdefl_fnd(&m2, s, max_chain, m.len + 1, in, i + 1, in_len);
  2453. m.len = (m2.len > m.len) ? 0 : m.len;
  2454. }
  2455. if (m.len >= SDEFL_MIN_MATCH) {
  2456. if (litlen) {
  2457. sdefl_seq(s, i - litlen, litlen);
  2458. litlen = 0;
  2459. }
  2460. sdefl_seq(s, -m.off, m.len);
  2461. sdefl_reg_match(s, m.off, m.len);
  2462. if (lvl < 2 && m.len >= nice_match) {
  2463. inc = m.len;
  2464. } else {
  2465. run = m.len;
  2466. }
  2467. } else {
  2468. s->freq.lit[in[i]]++;
  2469. litlen++;
  2470. }
  2471. run_inc = run * inc;
  2472. if (in_len - (i + run_inc) > SDEFL_MIN_MATCH) {
  2473. while (run-- > 0) {
  2474. unsigned h = sdefl_hash32(&in[i]);
  2475. s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
  2476. s->tbl[h] = i, i += inc;
  2477. assert(i <= blk_end);
  2478. }
  2479. } else {
  2480. i += run_inc;
  2481. assert(i <= blk_end);
  2482. }
  2483. }
  2484. if (litlen) {
  2485. sdefl_seq(s, i - litlen, litlen);
  2486. litlen = 0;
  2487. }
  2488. sdefl_flush(&q, s, blk_end == in_len, in, blk_begin, blk_end);
  2489. } while (i < in_len);
  2490. if (s->bitcnt) {
  2491. sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
  2492. }
  2493. assert(s->bitcnt == 0);
  2494. return (int)(q - out);
  2495. }
  2496. extern int
  2497. sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
  2498. s->bits = s->bitcnt = 0;
  2499. return sdefl_compr(s, (unsigned char*)out, (const unsigned char*)in, n, lvl);
  2500. }
  2501. static unsigned
  2502. sdefl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
  2503. #define SDEFL_ADLER_INIT (1)
  2504. const unsigned ADLER_MOD = 65521;
  2505. unsigned s1 = adler32 & 0xffff;
  2506. unsigned s2 = adler32 >> 16;
  2507. unsigned blk_len, i;
  2508. blk_len = in_len % 5552;
  2509. while (in_len) {
  2510. for (i = 0; i + 7 < blk_len; i += 8) {
  2511. s1 += in[0]; s2 += s1;
  2512. s1 += in[1]; s2 += s1;
  2513. s1 += in[2]; s2 += s1;
  2514. s1 += in[3]; s2 += s1;
  2515. s1 += in[4]; s2 += s1;
  2516. s1 += in[5]; s2 += s1;
  2517. s1 += in[6]; s2 += s1;
  2518. s1 += in[7]; s2 += s1;
  2519. in += 8;
  2520. }
  2521. for (; i < blk_len; ++i) {
  2522. s1 += *in++, s2 += s1;
  2523. }
  2524. s1 %= ADLER_MOD;
  2525. s2 %= ADLER_MOD;
  2526. in_len -= blk_len;
  2527. blk_len = 5552;
  2528. }
  2529. return (unsigned)(s2 << 16) + (unsigned)s1;
  2530. }
  2531. extern int
  2532. zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
  2533. int p = 0;
  2534. unsigned a = 0;
  2535. unsigned char *q = (unsigned char*)out;
  2536. s->bits = s->bitcnt = 0;
  2537. sdefl_put(&q, s, 0x78, 8); /* deflate, 32k window */
  2538. sdefl_put(&q, s, 0x01, 8); /* fast compression */
  2539. q += sdefl_compr(s, q, (const unsigned char*)in, n, lvl);
  2540. /* append adler checksum */
  2541. a = sdefl_adler32(SDEFL_ADLER_INIT, (const unsigned char*)in, n);
  2542. for (p = 0; p < 4; ++p) {
  2543. sdefl_put(&q, s, (a >> 24) & 0xFF, 8);
  2544. a <<= 8;
  2545. }
  2546. return (int)(q - (unsigned char*)out);
  2547. }
  2548. extern int
  2549. sdefl_bound(int len) {
  2550. int max_blocks = 1 + sdefl_div_round_up(len, SDEFL_RAW_BLK_SIZE);
  2551. int bound = 5 * max_blocks + len + 1 + 4 + 8;
  2552. return bound;
  2553. }
  2554. #endif /* SDEFL_IMPLEMENTATION */
  2555. //=========================================================================
  2556. // SINFL
  2557. // DEFLATE DECOMPRESSION algorithm: https://github.com/vurtun/lib/sinfl.h
  2558. //=========================================================================
  2559. #ifdef SINFL_IMPLEMENTATION
  2560. #include <string.h> /* memcpy, memset */
  2561. #include <assert.h> /* assert */
  2562. #if defined(__GNUC__) || defined(__clang__)
  2563. #define sinfl_likely(x) __builtin_expect((x),1)
  2564. #define sinfl_unlikely(x) __builtin_expect((x),0)
  2565. #else
  2566. #define sinfl_likely(x) (x)
  2567. #define sinfl_unlikely(x) (x)
  2568. #endif
  2569. #ifndef SINFL_NO_SIMD
  2570. #if defined(__x86_64__) || defined(_WIN32) || defined(_WIN64)
  2571. #include <emmintrin.h>
  2572. #define sinfl_char16 __m128i
  2573. #define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p))
  2574. #define sinfl_char16_str(d,v) _mm_storeu_si128((__m128i*)(void*)(d), v)
  2575. #define sinfl_char16_char(c) _mm_set1_epi8(c)
  2576. #elif defined(__arm__) || defined(__aarch64__)
  2577. #include <arm_neon.h>
  2578. #define sinfl_char16 uint8x16_t
  2579. #define sinfl_char16_ld(p) vld1q_u8((const unsigned char*)(p))
  2580. #define sinfl_char16_str(d,v) vst1q_u8((uint8_t*)(d), v)
  2581. #define sinfl_char16_char(c) vdupq_n_u8(c)
  2582. #else
  2583. #define SINFL_NO_SIMD
  2584. #endif
  2585. #endif
  2586. static int
  2587. sinfl_bsr(unsigned n) {
  2588. #ifdef _MSC_VER
  2589. _BitScanReverse(&n, n);
  2590. return n;
  2591. #elif defined(__GNUC__) || defined(__clang__)
  2592. return 31 - __builtin_clz(n);
  2593. #endif
  2594. }
  2595. static unsigned long long
  2596. sinfl_read64(const void *p) {
  2597. unsigned long long n;
  2598. memcpy(&n, p, 8);
  2599. return n;
  2600. }
  2601. static void
  2602. sinfl_copy64(unsigned char **dst, unsigned char **src) {
  2603. unsigned long long n;
  2604. memcpy(&n, *src, 8);
  2605. memcpy(*dst, &n, 8);
  2606. *dst += 8, *src += 8;
  2607. }
  2608. static unsigned char*
  2609. sinfl_write64(unsigned char *dst, unsigned long long w) {
  2610. memcpy(dst, &w, 8);
  2611. return dst + 8;
  2612. }
  2613. #ifndef SINFL_NO_SIMD
  2614. static unsigned char*
  2615. sinfl_write128(unsigned char *dst, sinfl_char16 w) {
  2616. sinfl_char16_str(dst, w);
  2617. return dst + 8;
  2618. }
  2619. static void
  2620. sinfl_copy128(unsigned char **dst, unsigned char **src) {
  2621. sinfl_char16 n = sinfl_char16_ld(*src);
  2622. sinfl_char16_str(*dst, n);
  2623. *dst += 16, *src += 16;
  2624. }
  2625. #endif
  2626. static void
  2627. sinfl_refill(struct sinfl *s) {
  2628. s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt;
  2629. s->bitptr += (63 - s->bitcnt) >> 3;
  2630. s->bitcnt |= 56; /* bitcount in range [56,63] */
  2631. }
  2632. static int
  2633. sinfl_peek(struct sinfl *s, int cnt) {
  2634. assert(cnt >= 0 && cnt <= 56);
  2635. assert(cnt <= s->bitcnt);
  2636. return s->bitbuf & ((1ull << cnt) - 1);
  2637. }
  2638. static void
  2639. sinfl_eat(struct sinfl *s, int cnt) {
  2640. assert(cnt <= s->bitcnt);
  2641. s->bitbuf >>= cnt;
  2642. s->bitcnt -= cnt;
  2643. }
  2644. static int
  2645. sinfl__get(struct sinfl *s, int cnt) {
  2646. int res = sinfl_peek(s, cnt);
  2647. sinfl_eat(s, cnt);
  2648. return res;
  2649. }
  2650. static int
  2651. sinfl_get(struct sinfl *s, int cnt) {
  2652. sinfl_refill(s);
  2653. return sinfl__get(s, cnt);
  2654. }
  2655. struct sinfl_gen {
  2656. int len;
  2657. int cnt;
  2658. int word;
  2659. short* sorted;
  2660. };
  2661. static int
  2662. sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
  2663. const int *cnt) {
  2664. int tbl_end = 0;
  2665. while (!(gen->cnt = cnt[gen->len])) {
  2666. ++gen->len;
  2667. }
  2668. tbl_end = 1 << gen->len;
  2669. while (gen->len <= tbl_bits) {
  2670. do {unsigned bit = 0;
  2671. tbl[gen->word] = (*gen->sorted++ << 16) | gen->len;
  2672. if (gen->word == tbl_end - 1) {
  2673. for (; gen->len < tbl_bits; gen->len++) {
  2674. memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
  2675. tbl_end <<= 1;
  2676. }
  2677. return 1;
  2678. }
  2679. bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1)));
  2680. gen->word &= bit - 1;
  2681. gen->word |= bit;
  2682. } while (--gen->cnt);
  2683. do {
  2684. if (++gen->len <= tbl_bits) {
  2685. memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
  2686. tbl_end <<= 1;
  2687. }
  2688. } while (!(gen->cnt = cnt[gen->len]));
  2689. }
  2690. return 0;
  2691. }
  2692. static void
  2693. sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
  2694. const int *cnt) {
  2695. int sub_bits = 0;
  2696. int sub_start = 0;
  2697. int sub_prefix = -1;
  2698. int tbl_end = 1 << tbl_bits;
  2699. while (1) {
  2700. unsigned entry;
  2701. int bit, stride, i;
  2702. /* start new sub-table */
  2703. if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
  2704. int used = 0;
  2705. sub_prefix = gen->word & ((1 << tbl_bits)-1);
  2706. sub_start = tbl_end;
  2707. sub_bits = gen->len - tbl_bits;
  2708. used = gen->cnt;
  2709. while (used < (1 << sub_bits)) {
  2710. sub_bits++;
  2711. used = (used << 1) + cnt[tbl_bits + sub_bits];
  2712. }
  2713. tbl_end = sub_start + (1 << sub_bits);
  2714. tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
  2715. }
  2716. /* fill sub-table */
  2717. entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
  2718. gen->sorted++;
  2719. i = sub_start + (gen->word >> tbl_bits);
  2720. stride = 1 << (gen->len - tbl_bits);
  2721. do {
  2722. tbl[i] = entry;
  2723. i += stride;
  2724. } while (i < tbl_end);
  2725. if (gen->word == (1 << gen->len)-1) {
  2726. return;
  2727. }
  2728. bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1));
  2729. gen->word &= bit - 1;
  2730. gen->word |= bit;
  2731. gen->cnt--;
  2732. while (!gen->cnt) {
  2733. gen->cnt = cnt[++gen->len];
  2734. }
  2735. }
  2736. }
  2737. static void
  2738. sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
  2739. int symcnt) {
  2740. int i, used = 0;
  2741. short sort[288];
  2742. int cnt[16] = {0}, off[16]= {0};
  2743. struct sinfl_gen gen = {0};
  2744. gen.sorted = sort;
  2745. gen.len = 1;
  2746. for (i = 0; i < symcnt; ++i)
  2747. cnt[lens[i]]++;
  2748. off[1] = cnt[0];
  2749. for (i = 1; i < maxlen; ++i) {
  2750. off[i + 1] = off[i] + cnt[i];
  2751. used = (used << 1) + cnt[i];
  2752. }
  2753. used = (used << 1) + cnt[i];
  2754. for (i = 0; i < symcnt; ++i)
  2755. gen.sorted[off[lens[i]]++] = (short)i;
  2756. gen.sorted += off[0];
  2757. if (used < (1 << maxlen)){
  2758. for (i = 0; i < 1 << tbl_bits; ++i)
  2759. tbl[i] = (0 << 16u) | 1;
  2760. return;
  2761. }
  2762. if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){
  2763. sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt);
  2764. }
  2765. }
  2766. static int
  2767. sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) {
  2768. int idx = sinfl_peek(s, bit_len);
  2769. unsigned key = tbl[idx];
  2770. if (key & 0x10) {
  2771. /* sub-table lookup */
  2772. int len = key & 0x0f;
  2773. sinfl_eat(s, bit_len);
  2774. idx = sinfl_peek(s, len);
  2775. key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
  2776. }
  2777. sinfl_eat(s, key & 0x0f);
  2778. return (key >> 16) & 0x0fff;
  2779. }
  2780. static int
  2781. sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) {
  2782. static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
  2783. static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
  2784. 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
  2785. static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
  2786. 10,10,11,11,12,12,13,13,0,0};
  2787. static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,
  2788. 43,51,59,67,83,99,115,131,163,195,227,258,0,0};
  2789. static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
  2790. 4,4,4,5,5,5,5,0,0,0};
  2791. const unsigned char *oe = out + cap;
  2792. const unsigned char *e = in + size, *o = out;
  2793. enum sinfl_states {hdr,stored,fixed,dyn,blk};
  2794. enum sinfl_states state = hdr;
  2795. struct sinfl s = {0};
  2796. int last = 0;
  2797. s.bitptr = in;
  2798. while (1) {
  2799. switch (state) {
  2800. case hdr: {
  2801. /* block header */
  2802. int type = 0;
  2803. sinfl_refill(&s);
  2804. last = sinfl__get(&s,1);
  2805. type = sinfl__get(&s,2);
  2806. switch (type) {default: return (int)(out-o);
  2807. case 0x00: state = stored; break;
  2808. case 0x01: state = fixed; break;
  2809. case 0x02: state = dyn; break;}
  2810. } break;
  2811. case stored: {
  2812. /* uncompressed block */
  2813. unsigned len, nlen;
  2814. sinfl__get(&s,s.bitcnt & 7);
  2815. len = (unsigned short)sinfl__get(&s,16);
  2816. nlen = (unsigned short)sinfl__get(&s,16);
  2817. s.bitptr -= s.bitcnt / 8;
  2818. s.bitbuf = s.bitcnt = 0;
  2819. if ((unsigned short)len != (unsigned short)~nlen)
  2820. return (int)(out-o);
  2821. if (len > (e - s.bitptr) || !len)
  2822. return (int)(out-o);
  2823. memcpy(out, s.bitptr, (size_t)len);
  2824. s.bitptr += len, out += len;
  2825. if (last) return (int)(out-o);
  2826. state = hdr;
  2827. } break;
  2828. case fixed: {
  2829. /* fixed huffman codes */
  2830. int n; unsigned char lens[288+32];
  2831. for (n = 0; n <= 143; n++) lens[n] = 8;
  2832. for (n = 144; n <= 255; n++) lens[n] = 9;
  2833. for (n = 256; n <= 279; n++) lens[n] = 7;
  2834. for (n = 280; n <= 287; n++) lens[n] = 8;
  2835. for (n = 0; n < 32; n++) lens[288+n] = 5;
  2836. /* build lit/dist tables */
  2837. sinfl_build(s.lits, lens, 10, 15, 288);
  2838. sinfl_build(s.dsts, lens + 288, 8, 15, 32);
  2839. state = blk;
  2840. } break;
  2841. case dyn: {
  2842. /* dynamic huffman codes */
  2843. int n, i;
  2844. unsigned hlens[SINFL_PRE_TBL_SIZE];
  2845. unsigned char nlens[19] = {0}, lens[288+32];
  2846. sinfl_refill(&s);
  2847. {int nlit = 257 + sinfl__get(&s,5);
  2848. int ndist = 1 + sinfl__get(&s,5);
  2849. int nlen = 4 + sinfl__get(&s,4);
  2850. for (n = 0; n < nlen; n++)
  2851. nlens[order[n]] = (unsigned char)sinfl_get(&s,3);
  2852. sinfl_build(hlens, nlens, 7, 7, 19);
  2853. /* decode code lengths */
  2854. for (n = 0; n < nlit + ndist;) {
  2855. int sym = 0;
  2856. sinfl_refill(&s);
  2857. sym = sinfl_decode(&s, hlens, 7);
  2858. switch (sym) {default: lens[n++] = (unsigned char)sym; break;
  2859. case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
  2860. case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break;
  2861. case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;}
  2862. }
  2863. /* build lit/dist tables */
  2864. sinfl_build(s.lits, lens, 10, 15, nlit);
  2865. sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
  2866. state = blk;}
  2867. } break;
  2868. case blk: {
  2869. /* decompress block */
  2870. while (1) {
  2871. int sym;
  2872. sinfl_refill(&s);
  2873. sym = sinfl_decode(&s, s.lits, 10);
  2874. if (sym < 256) {
  2875. /* literal */
  2876. if (sinfl_unlikely(out >= oe)) {
  2877. return (int)(out-o);
  2878. }
  2879. *out++ = (unsigned char)sym;
  2880. sym = sinfl_decode(&s, s.lits, 10);
  2881. if (sym < 256) {
  2882. *out++ = (unsigned char)sym;
  2883. continue;
  2884. }
  2885. }
  2886. if (sinfl_unlikely(sym == 256)) {
  2887. /* end of block */
  2888. if (last) return (int)(out-o);
  2889. state = hdr;
  2890. break;
  2891. }
  2892. /* match */
  2893. if (sym >= 286) {
  2894. /* length codes 286 and 287 must not appear in compressed data */
  2895. return (int)(out-o);
  2896. }
  2897. sym -= 257;
  2898. {int len = sinfl__get(&s, lbits[sym]) + lbase[sym];
  2899. int dsym = sinfl_decode(&s, s.dsts, 8);
  2900. int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym];
  2901. unsigned char *dst = out, *src = out - offs;
  2902. if (sinfl_unlikely(offs > (int)(out-o))) {
  2903. return (int)(out-o);
  2904. }
  2905. out = out + len;
  2906. #ifndef SINFL_NO_SIMD
  2907. if (sinfl_likely(oe - out >= 16 * 3)) {
  2908. if (offs >= 16) {
  2909. /* simd copy match */
  2910. sinfl_copy128(&dst, &src);
  2911. sinfl_copy128(&dst, &src);
  2912. do sinfl_copy128(&dst, &src);
  2913. while (dst < out);
  2914. } else if (offs >= 8) {
  2915. /* word copy match */
  2916. sinfl_copy64(&dst, &src);
  2917. sinfl_copy64(&dst, &src);
  2918. do sinfl_copy64(&dst, &src);
  2919. while (dst < out);
  2920. } else if (offs == 1) {
  2921. /* rle match copying */
  2922. sinfl_char16 w = sinfl_char16_char(src[0]);
  2923. dst = sinfl_write128(dst, w);
  2924. dst = sinfl_write128(dst, w);
  2925. do dst = sinfl_write128(dst, w);
  2926. while (dst < out);
  2927. } else {
  2928. /* byte copy match */
  2929. *dst++ = *src++;
  2930. *dst++ = *src++;
  2931. do *dst++ = *src++;
  2932. while (dst < out);
  2933. }
  2934. }
  2935. #else
  2936. if (sinfl_likely(oe - out >= 3 * 8 - 3)) {
  2937. if (offs >= 8) {
  2938. /* word copy match */
  2939. sinfl_copy64(&dst, &src);
  2940. sinfl_copy64(&dst, &src);
  2941. do sinfl_copy64(&dst, &src);
  2942. while (dst < out);
  2943. } else if (offs == 1) {
  2944. /* rle match copying */
  2945. unsigned int c = src[0];
  2946. unsigned int hw = (c << 24u) | (c << 16u) | (c << 8u) | (unsigned)c;
  2947. unsigned long long w = (unsigned long long)hw << 32llu | hw;
  2948. dst = sinfl_write64(dst, w);
  2949. dst = sinfl_write64(dst, w);
  2950. do dst = sinfl_write64(dst, w);
  2951. while (dst < out);
  2952. } else {
  2953. /* byte copy match */
  2954. *dst++ = *src++;
  2955. *dst++ = *src++;
  2956. do *dst++ = *src++;
  2957. while (dst < out);
  2958. }
  2959. }
  2960. #endif
  2961. else {
  2962. *dst++ = *src++;
  2963. *dst++ = *src++;
  2964. do *dst++ = *src++;
  2965. while (dst < out);
  2966. }}
  2967. }
  2968. } break;}
  2969. }
  2970. return (int)(out-o);
  2971. }
  2972. extern int
  2973. sinflate(void *out, int cap, const void *in, int size) {
  2974. return sinfl_decompress((unsigned char*)out, cap, (const unsigned char*)in, size);
  2975. }
  2976. static unsigned
  2977. sinfl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
  2978. const unsigned ADLER_MOD = 65521;
  2979. unsigned s1 = adler32 & 0xffff;
  2980. unsigned s2 = adler32 >> 16;
  2981. unsigned blk_len, i;
  2982. blk_len = in_len % 5552;
  2983. while (in_len) {
  2984. for (i=0; i + 7 < blk_len; i += 8) {
  2985. s1 += in[0]; s2 += s1;
  2986. s1 += in[1]; s2 += s1;
  2987. s1 += in[2]; s2 += s1;
  2988. s1 += in[3]; s2 += s1;
  2989. s1 += in[4]; s2 += s1;
  2990. s1 += in[5]; s2 += s1;
  2991. s1 += in[6]; s2 += s1;
  2992. s1 += in[7]; s2 += s1;
  2993. in += 8;
  2994. }
  2995. for (; i < blk_len; ++i)
  2996. s1 += *in++, s2 += s1;
  2997. s1 %= ADLER_MOD; s2 %= ADLER_MOD;
  2998. in_len -= blk_len;
  2999. blk_len = 5552;
  3000. } return (unsigned)(s2 << 16) + (unsigned)s1;
  3001. }
  3002. extern int
  3003. zsinflate(void *out, int cap, const void *mem, int size) {
  3004. const unsigned char *in = (const unsigned char*)mem;
  3005. if (size >= 6) {
  3006. const unsigned char *eob = in + size - 4;
  3007. int n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size);
  3008. unsigned a = sinfl_adler32(1u, (unsigned char*)out, n);
  3009. unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0;
  3010. return a == h ? n : -1;
  3011. } else {
  3012. return -1;
  3013. }
  3014. }
  3015. #endif /* SINFL_IMPLEMENTATION */
  3016. /*
  3017. # Small Deflate
  3018. `sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
  3019. which implements the Deflate (RFC 1951) compressed data format specification standard.
  3020. It is mainly tuned to get as much speed and compression ratio from as little code
  3021. as needed to keep the implementation as concise as possible.
  3022. ## Features
  3023. - Portable single header and source file duo written in ANSI C (ISO C90)
  3024. - Dual license with either MIT or public domain
  3025. - Small implementation
  3026. - Deflate: 525 LoC
  3027. - Inflate: 500 LoC
  3028. - Webassembly:
  3029. - Deflate ~3.7 KB (~2.2KB compressed)
  3030. - Inflate ~3.6 KB (~2.2KB compressed)
  3031. ## Usage:
  3032. This file behaves differently depending on what symbols you define
  3033. before including it.
  3034. Header-File mode:
  3035. If you do not define `SINFL_IMPLEMENTATION` before including this file, it
  3036. will operate in header only mode. In this mode it declares all used structs
  3037. and the API of the library without including the implementation of the library.
  3038. Implementation mode:
  3039. If you define `SINFL_IMPLEMENTATION` before including this file, it will
  3040. compile the implementation. Make sure that you only include
  3041. this file implementation in *one* C or C++ file to prevent collisions.
  3042. ### Benchmark
  3043. | Compressor name | Compression| Decompress.| Compr. size | Ratio |
  3044. | ------------------------| -----------| -----------| ----------- | ----- |
  3045. | miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
  3046. | miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
  3047. | miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
  3048. | zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
  3049. | zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
  3050. | zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
  3051. | sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
  3052. | sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
  3053. | sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
  3054. | sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
  3055. | libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
  3056. | libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
  3057. | libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
  3058. | libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
  3059. ### Compression
  3060. Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
  3061. | File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
  3062. | --------| -----------| -------------| ---------- | ------------|
  3063. | dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
  3064. | mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
  3065. | mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
  3066. | nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
  3067. | ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
  3068. | osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
  3069. | reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
  3070. | samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
  3071. | sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
  3072. | webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
  3073. | xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
  3074. | x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
  3075. ## License
  3076. ```
  3077. ------------------------------------------------------------------------------
  3078. This software is available under 2 licenses -- choose whichever you prefer.
  3079. ------------------------------------------------------------------------------
  3080. ALTERNATIVE A - MIT License
  3081. Copyright (c) 2020 Micha Mettke
  3082. Permission is hereby granted, free of charge, to any person obtaining a copy of
  3083. this software and associated documentation files (the "Software"), to deal in
  3084. the Software without restriction, including without limitation the rights to
  3085. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  3086. of the Software, and to permit persons to whom the Software is furnished to do
  3087. so, subject to the following conditions:
  3088. The above copyright notice and this permission notice shall be included in all
  3089. copies or substantial portions of the Software.
  3090. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3091. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3092. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3093. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  3094. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  3095. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  3096. SOFTWARE.
  3097. ------------------------------------------------------------------------------
  3098. ALTERNATIVE B - Public Domain (www.unlicense.org)
  3099. This is free and unencumbered software released into the public domain.
  3100. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  3101. software, either in source code form or as a compiled binary, for any purpose,
  3102. commercial or non-commercial, and by any means.
  3103. In jurisdictions that recognize copyright laws, the author or authors of this
  3104. software dedicate any and all copyright interest in the software to the public
  3105. domain. We make this dedication for the benefit of the public at large and to
  3106. the detriment of our heirs and successors. We intend this dedication to be an
  3107. overt act of relinquishment in perpetuity of all present and future rights to
  3108. this software under copyright law.
  3109. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3110. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3111. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3112. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  3113. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  3114. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3115. ------------------------------------------------------------------------------
  3116. ```
  3117. */
  3118. #endif // RPNG_DEFLATE_IMPLEMENTATION
  3119. #endif // RPNG_IMPLEMENTATION