common.odin 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615
  1. /*
  2. Copyright 2021 Jeroen van Rijn <[email protected]>.
  3. Made available under Odin's BSD-3 license.
  4. List of contributors:
  5. Jeroen van Rijn: Initial implementation, optimization.
  6. Ginger Bill: Cosmetic changes.
  7. */
  8. // package image implements a general 2D image library to be used with other image related packages
  9. package image
  10. import "core:bytes"
  11. import "core:mem"
  12. import "core:io"
  13. import "core:compress"
  14. import "base:runtime"
  15. /*
  16. 67_108_864 pixels max by default.
  17. For QOI, the Worst case scenario means all pixels will be encoded as RGBA literals, costing 5 bytes each.
  18. This caps memory usage at 320 MiB.
  19. The tunable is limited to 4_294_836_225 pixels maximum, or 4 GiB per 8-bit channel.
  20. It is not advised to tune it this large.
  21. The 64 Megapixel default is considered to be a decent upper bound you won't run into in practice,
  22. except in very specific circumstances.
  23. */
  24. MAX_DIMENSIONS :: min(#config(MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535)
  25. // Color
  26. RGB_Pixel :: [3]u8
  27. RGBA_Pixel :: [4]u8
  28. RGB_Pixel_16 :: [3]u16
  29. RGBA_Pixel_16 :: [4]u16
  30. // Grayscale
  31. G_Pixel :: [1]u8
  32. GA_Pixel :: [2]u8
  33. G_Pixel_16 :: [1]u16
  34. GA_Pixel_16 :: [2]u16
  35. Image :: struct {
  36. width: int,
  37. height: int,
  38. channels: int,
  39. depth: int, // Channel depth in bits, typically 8 or 16
  40. pixels: bytes.Buffer `fmt:"-"`,
  41. /*
  42. Some image loaders/writers can return/take an optional background color.
  43. For convenience, we return them as u16 so we don't need to switch on the type
  44. in our viewer, and can just test against nil.
  45. */
  46. background: Maybe(RGB_Pixel_16),
  47. metadata: Image_Metadata,
  48. which: Which_File_Type,
  49. }
  50. Image_Metadata :: union #shared_nil {
  51. ^Netpbm_Info,
  52. ^PNG_Info,
  53. ^QOI_Info,
  54. ^TGA_Info,
  55. ^BMP_Info,
  56. ^JPEG_Info,
  57. }
  58. Exif :: struct {
  59. byte_order: enum {
  60. little_endian,
  61. big_endian,
  62. },
  63. data: []u8 `fmt:"-"`,
  64. }
  65. /*
  66. IMPORTANT: `.do_not_expand_*` options currently skip handling of the `alpha_*` options,
  67. therefore Gray+Alpha will be returned as such even if you add `.alpha_drop_if_present`,
  68. and `.alpha_add_if_missing` and keyed transparency will likewise be ignored.
  69. The same goes for indexed images. This will be remedied in a near future update.
  70. */
  71. /*
  72. Image_Option:
  73. `.info`
  74. This option behaves as `.return_metadata` and `.do_not_decompress_image` and can be used
  75. to gather an image's dimensions and color information.
  76. `.return_header`
  77. Fill out img.metadata.header with the image's format-specific header struct.
  78. If we only care about the image specs, we can set `.return_header` +
  79. `.do_not_decompress_image`, or `.info`.
  80. `.return_metadata`
  81. Returns all chunks not needed to decode the data.
  82. It also returns the header as if `.return_header` was set.
  83. `.do_not_decompress_image`
  84. Skip decompressing IDAT chunk, defiltering and the rest.
  85. `.do_not_expand_grayscale`
  86. Do not turn grayscale (+ Alpha) images into RGB(A).
  87. Returns just the 1 or 2 channels present, although 1, 2 and 4 bit are still scaled to 8-bit.
  88. `.do_not_expand_indexed`
  89. Do not turn indexed (+ Alpha) images into RGB(A).
  90. Returns just the 1 or 2 (with `tRNS`) channels present.
  91. Make sure to use `return_metadata` to also return the palette chunk so you can recolor it yourself.
  92. `.do_not_expand_channels`
  93. Applies both `.do_not_expand_grayscale` and `.do_not_expand_indexed`.
  94. `.alpha_add_if_missing`
  95. If the image has no alpha channel, it'll add one set to max(type).
  96. Turns RGB into RGBA and Gray into Gray+Alpha
  97. `.alpha_drop_if_present`
  98. If the image has an alpha channel, drop it.
  99. You may want to use `.alpha_premultiply` in this case.
  100. NOTE: For PNG, this also skips handling of the tRNS chunk, if present,
  101. unless you select `alpha_premultiply`.
  102. In this case it'll premultiply the specified pixels in question only,
  103. as the others are implicitly fully opaque.
  104. `.alpha_premultiply`
  105. If the image has an alpha channel, returns image data as follows:
  106. RGB *= A, Gray = Gray *= A
  107. `.blend_background`
  108. If a bKGD chunk is present in a PNG, we normally just set `img.background`
  109. with its value and leave it up to the application to decide how to display the image,
  110. as per the PNG specification.
  111. With `.blend_background` selected, we blend the image against the background
  112. color. As this negates the use for an alpha channel, we'll drop it _unless_
  113. you also specify `.alpha_add_if_missing`.
  114. Options that don't apply to an image format will be ignored by their loader.
  115. */
  116. Option :: enum {
  117. // LOAD OPTIONS
  118. info = 0,
  119. do_not_decompress_image,
  120. return_header,
  121. return_metadata,
  122. alpha_add_if_missing, // Ignored for QOI. Always returns RGBA8.
  123. alpha_drop_if_present, // Unimplemented for QOI. Returns error.
  124. alpha_premultiply, // Unimplemented for QOI. Returns error.
  125. blend_background, // Ignored for non-PNG formats
  126. // Unimplemented
  127. do_not_expand_grayscale,
  128. do_not_expand_indexed,
  129. do_not_expand_channels,
  130. // SAVE OPTIONS
  131. qoi_all_channels_linear, // QOI, informative only. If not set, defaults to sRGB with linear alpha.
  132. }
  133. Options :: distinct bit_set[Option]
  134. Error :: union #shared_nil {
  135. General_Image_Error,
  136. Netpbm_Error,
  137. PNG_Error,
  138. QOI_Error,
  139. BMP_Error,
  140. JPEG_Error,
  141. compress.Error,
  142. compress.General_Error,
  143. compress.Deflate_Error,
  144. compress.ZLIB_Error,
  145. io.Error,
  146. runtime.Allocator_Error,
  147. }
  148. General_Image_Error :: enum {
  149. None = 0,
  150. Unsupported_Option,
  151. // File I/O
  152. Unable_To_Read_File,
  153. Unable_To_Write_File,
  154. // Invalid
  155. Unsupported_Format,
  156. Invalid_Signature,
  157. Invalid_Input_Image,
  158. Image_Dimensions_Too_Large,
  159. Invalid_Image_Dimensions,
  160. Invalid_Number_Of_Channels,
  161. Image_Does_Not_Adhere_to_Spec,
  162. Invalid_Image_Depth,
  163. Invalid_Bit_Depth,
  164. Invalid_Color_Space,
  165. // More data than pixels to decode into, for example.
  166. Corrupt,
  167. // Output buffer is the wrong size
  168. Invalid_Output,
  169. // Allocation
  170. Unable_To_Allocate_Or_Resize,
  171. }
  172. /*
  173. BMP-specific
  174. */
  175. BMP_Error :: enum {
  176. None = 0,
  177. Invalid_File_Size,
  178. Unsupported_BMP_Version,
  179. Unsupported_OS2_File,
  180. Unsupported_Compression,
  181. Unsupported_BPP,
  182. Invalid_Stride,
  183. Invalid_Color_Count,
  184. Implausible_File_Size,
  185. Bitfield_Version_Unhandled, // We don't (yet) handle bit fields for this BMP version.
  186. Bitfield_Sum_Exceeds_BPP, // Total mask bit count > bpp
  187. Bitfield_Overlapped, // Channel masks overlap
  188. }
  189. // img.metadata is wrapped in a struct in case we need to add to it later
  190. // without putting it in BMP_Header
  191. BMP_Info :: struct {
  192. info: BMP_Header,
  193. }
  194. BMP_Magic :: enum u16le {
  195. Bitmap = 0x4d42, // 'BM'
  196. OS2_Bitmap_Array = 0x4142, // 'BA'
  197. OS2_Icon = 0x4349, // 'IC',
  198. OS2_Color_Icon = 0x4943, // 'CI'
  199. OS2_Pointer = 0x5450, // 'PT'
  200. OS2_Color_Pointer = 0x5043, // 'CP'
  201. }
  202. // See: http://justsolve.archiveteam.org/wiki/BMP#Well-known_versions
  203. BMP_Version :: enum u32le {
  204. OS2_v1 = 12, // BITMAPCOREHEADER (Windows V2 / OS/2 version 1.0)
  205. OS2_v2 = 64, // BITMAPCOREHEADER2 (OS/2 version 2.x)
  206. V3 = 40, // BITMAPINFOHEADER
  207. V4 = 108, // BITMAPV4HEADER
  208. V5 = 124, // BITMAPV5HEADER
  209. ABBR_16 = 16, // Abbreviated
  210. ABBR_24 = 24, // ..
  211. ABBR_48 = 48, // ..
  212. ABBR_52 = 52, // ..
  213. ABBR_56 = 56, // ..
  214. }
  215. BMP_Header :: struct #packed {
  216. // File header
  217. magic: BMP_Magic,
  218. size: u32le,
  219. _res1: u16le, // Reserved; must be zero
  220. _res2: u16le, // Reserved; must be zero
  221. pixel_offset: u32le, // Offset in bytes, from the beginning of BMP_Header to the pixel data
  222. // V3
  223. info_size: BMP_Version,
  224. width: i32le,
  225. height: i32le,
  226. planes: u16le,
  227. bpp: u16le,
  228. compression: BMP_Compression,
  229. image_size: u32le,
  230. pels_per_meter: [2]u32le,
  231. colors_used: u32le,
  232. colors_important: u32le, // OS2_v2 is equal up to here
  233. // V4
  234. masks: [4]u32le `fmt:"32b"`,
  235. colorspace: BMP_Logical_Color_Space,
  236. endpoints: BMP_CIEXYZTRIPLE,
  237. gamma: [3]BMP_GAMMA16_16,
  238. // V5
  239. intent: BMP_Gamut_Mapping_Intent,
  240. profile_data: u32le,
  241. profile_size: u32le,
  242. reserved: u32le,
  243. }
  244. #assert(size_of(BMP_Header) == 138)
  245. OS2_Header :: struct #packed {
  246. // BITMAPCOREHEADER minus info_size field
  247. width: i16le,
  248. height: i16le,
  249. planes: u16le,
  250. bpp: u16le,
  251. }
  252. #assert(size_of(OS2_Header) == 8)
  253. BMP_Compression :: enum u32le {
  254. RGB = 0x0000,
  255. RLE8 = 0x0001,
  256. RLE4 = 0x0002,
  257. Bit_Fields = 0x0003, // If Windows
  258. Huffman1D = 0x0003, // If OS2v2
  259. JPEG = 0x0004, // If Windows
  260. RLE24 = 0x0004, // If OS2v2
  261. PNG = 0x0005,
  262. Alpha_Bit_Fields = 0x0006,
  263. CMYK = 0x000B,
  264. CMYK_RLE8 = 0x000C,
  265. CMYK_RLE4 = 0x000D,
  266. }
  267. BMP_Logical_Color_Space :: enum u32le {
  268. CALIBRATED_RGB = 0x00000000,
  269. sRGB = 0x73524742, // 'sRGB'
  270. WINDOWS_COLOR_SPACE = 0x57696E20, // 'Win '
  271. }
  272. BMP_FXPT2DOT30 :: u32le
  273. BMP_CIEXYZ :: [3]BMP_FXPT2DOT30
  274. BMP_CIEXYZTRIPLE :: [3]BMP_CIEXYZ
  275. BMP_GAMMA16_16 :: [2]u16le
  276. BMP_Gamut_Mapping_Intent :: enum u32le {
  277. INVALID = 0x00000000, // If not V5, this field will just be zero-initialized and not valid.
  278. ABS_COLORIMETRIC = 0x00000008,
  279. BUSINESS = 0x00000001,
  280. GRAPHICS = 0x00000002,
  281. IMAGES = 0x00000004,
  282. }
  283. /*
  284. Netpbm-specific definitions
  285. */
  286. Netpbm_Format :: enum {
  287. P1, P2, P3, P4, P5, P6, P7, Pf, PF,
  288. }
  289. Netpbm_Header :: struct {
  290. format: Netpbm_Format,
  291. width: int,
  292. height: int,
  293. channels: int,
  294. depth: int,
  295. maxval: int,
  296. tupltype: string,
  297. scale: f32,
  298. little_endian: bool,
  299. }
  300. Netpbm_Info :: struct {
  301. header: Netpbm_Header,
  302. }
  303. Netpbm_Error :: enum {
  304. None = 0,
  305. // reading
  306. Invalid_Header_Token_Character,
  307. Incomplete_Header,
  308. Invalid_Header_Value,
  309. Duplicate_Header_Field,
  310. Buffer_Too_Small,
  311. Invalid_Buffer_ASCII_Token,
  312. Invalid_Buffer_Value,
  313. // writing
  314. Invalid_Format,
  315. }
  316. /*
  317. PNG-specific definitions
  318. */
  319. PNG_Error :: enum {
  320. None = 0,
  321. IHDR_Not_First_Chunk,
  322. IHDR_Corrupt,
  323. IDAT_Missing,
  324. IDAT_Must_Be_Contiguous,
  325. IDAT_Corrupt,
  326. IDAT_Size_Too_Large,
  327. PLTE_Encountered_Unexpectedly,
  328. PLTE_Invalid_Length,
  329. PLTE_Missing,
  330. TRNS_Encountered_Unexpectedly,
  331. TNRS_Invalid_Length,
  332. BKGD_Invalid_Length,
  333. Unknown_Color_Type,
  334. Invalid_Color_Bit_Depth_Combo,
  335. Unknown_Filter_Method,
  336. Unknown_Interlace_Method,
  337. Requested_Channel_Not_Present,
  338. Post_Processing_Error,
  339. Invalid_Chunk_Length,
  340. }
  341. PNG_Info :: struct {
  342. header: PNG_IHDR,
  343. chunks: [dynamic]PNG_Chunk,
  344. }
  345. PNG_Chunk_Header :: struct #packed {
  346. length: u32be,
  347. type: PNG_Chunk_Type,
  348. }
  349. PNG_Chunk :: struct #packed {
  350. header: PNG_Chunk_Header,
  351. data: []byte,
  352. crc: u32be,
  353. }
  354. PNG_Chunk_Type :: enum u32be {
  355. // IHDR must come first in a file
  356. IHDR = 'I' << 24 | 'H' << 16 | 'D' << 8 | 'R',
  357. // PLTE must precede the first IDAT chunk
  358. PLTE = 'P' << 24 | 'L' << 16 | 'T' << 8 | 'E',
  359. bKGD = 'b' << 24 | 'K' << 16 | 'G' << 8 | 'D',
  360. tRNS = 't' << 24 | 'R' << 16 | 'N' << 8 | 'S',
  361. IDAT = 'I' << 24 | 'D' << 16 | 'A' << 8 | 'T',
  362. iTXt = 'i' << 24 | 'T' << 16 | 'X' << 8 | 't',
  363. tEXt = 't' << 24 | 'E' << 16 | 'X' << 8 | 't',
  364. zTXt = 'z' << 24 | 'T' << 16 | 'X' << 8 | 't',
  365. iCCP = 'i' << 24 | 'C' << 16 | 'C' << 8 | 'P',
  366. pHYs = 'p' << 24 | 'H' << 16 | 'Y' << 8 | 's',
  367. gAMA = 'g' << 24 | 'A' << 16 | 'M' << 8 | 'A',
  368. tIME = 't' << 24 | 'I' << 16 | 'M' << 8 | 'E',
  369. sPLT = 's' << 24 | 'P' << 16 | 'L' << 8 | 'T',
  370. sRGB = 's' << 24 | 'R' << 16 | 'G' << 8 | 'B',
  371. hIST = 'h' << 24 | 'I' << 16 | 'S' << 8 | 'T',
  372. cHRM = 'c' << 24 | 'H' << 16 | 'R' << 8 | 'M',
  373. sBIT = 's' << 24 | 'B' << 16 | 'I' << 8 | 'T',
  374. /*
  375. eXIf tags are not part of the core spec, but have been ratified
  376. in v1.5.0 of the PNG Ext register.
  377. We will provide unprocessed chunks to the caller if `.return_metadata` is set.
  378. Applications are free to implement an Exif decoder.
  379. */
  380. eXIf = 'e' << 24 | 'X' << 16 | 'I' << 8 | 'f',
  381. // PNG files must end with IEND
  382. IEND = 'I' << 24 | 'E' << 16 | 'N' << 8 | 'D',
  383. /*
  384. XCode sometimes produces "PNG" files that don't adhere to the PNG spec.
  385. We recognize them only in order to avoid doing further work on them.
  386. Some tools like PNG Defry may be able to repair them, but we're not
  387. going to reward Apple for producing proprietary broken files purporting
  388. to be PNGs by supporting them.
  389. */
  390. iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T',
  391. CgBI = 'C' << 24 | 'g' << 16 | 'B' << 8 | 'I',
  392. }
  393. PNG_IHDR :: struct #packed {
  394. width: u32be,
  395. height: u32be,
  396. bit_depth: u8,
  397. color_type: PNG_Color_Type,
  398. compression_method: u8,
  399. filter_method: u8,
  400. interlace_method: PNG_Interlace_Method,
  401. }
  402. PNG_IHDR_SIZE :: size_of(PNG_IHDR)
  403. #assert (PNG_IHDR_SIZE == 13)
  404. PNG_Color_Value :: enum u8 {
  405. Paletted = 0, // 1 << 0 = 1
  406. Color = 1, // 1 << 1 = 2
  407. Alpha = 2, // 1 << 2 = 4
  408. }
  409. PNG_Color_Type :: distinct bit_set[PNG_Color_Value; u8]
  410. PNG_Interlace_Method :: enum u8 {
  411. None = 0,
  412. Adam7 = 1,
  413. }
  414. /*
  415. QOI-specific definitions
  416. */
  417. QOI_Error :: enum {
  418. None = 0,
  419. Missing_Or_Corrupt_Trailer, // Image seemed to have decoded okay, but trailer is missing or corrupt.
  420. }
  421. QOI_Magic :: u32be(0x716f6966) // "qoif"
  422. QOI_Color_Space :: enum u8 {
  423. sRGB = 0,
  424. Linear = 1,
  425. }
  426. QOI_Header :: struct #packed {
  427. magic: u32be,
  428. width: u32be,
  429. height: u32be,
  430. channels: u8,
  431. color_space: QOI_Color_Space,
  432. }
  433. #assert(size_of(QOI_Header) == 14)
  434. QOI_Info :: struct {
  435. header: QOI_Header,
  436. }
  437. TGA_Data_Type :: enum u8 {
  438. No_Image_Data = 0,
  439. Uncompressed_Color_Mapped = 1,
  440. Uncompressed_RGB = 2,
  441. Uncompressed_Black_White = 3,
  442. Compressed_Color_Mapped = 9,
  443. Compressed_RGB = 10,
  444. Compressed_Black_White = 11,
  445. }
  446. TGA_Header :: struct #packed {
  447. id_length: u8,
  448. color_map_type: u8,
  449. data_type_code: TGA_Data_Type,
  450. color_map_origin: u16le,
  451. color_map_length: u16le,
  452. color_map_depth: u8,
  453. origin: [2]u16le,
  454. dimensions: [2]u16le,
  455. bits_per_pixel: u8,
  456. image_descriptor: u8,
  457. }
  458. #assert(size_of(TGA_Header) == 18)
  459. New_TGA_Signature :: "TRUEVISION-XFILE.\x00"
  460. TGA_Footer :: struct #packed {
  461. extension_area_offset: u32le,
  462. developer_directory_offset: u32le,
  463. signature: [18]u8 `fmt:"s,0"`, // Should match signature if New TGA.
  464. }
  465. #assert(size_of(TGA_Footer) == 26)
  466. TGA_Extension :: struct #packed {
  467. extension_size: u16le, // Size of this struct. If not 495 bytes it means it's an unsupported version.
  468. author_name: [41]u8 `fmt:"s,0"`, // Author name, ASCII. Zero-terminated
  469. author_comments: [324]u8 `fmt:"s,0"`, // Author comments, formatted as 4 lines of 80 character lines, each zero terminated.
  470. datetime: struct {month, day, year, hour, minute, second: u16le},
  471. job_name: [41]u8 `fmt:"s,0"`, // Author name, ASCII. Zero-terminated
  472. job_time: struct {hour, minute, second: u16le},
  473. software_id: [41]u8 `fmt:"s,0"`, // Software ID name, ASCII. Zero-terminated
  474. software_version: struct #packed {
  475. number: u16le, // Version number * 100
  476. letter: u8 `fmt:"r"`, // " " if not used
  477. },
  478. key_color: [4]u8, // ARGB key color used at time of production
  479. aspect_ratio: [2]u16le, // Numerator / Denominator
  480. gamma: [2]u16le, // Numerator / Denominator, range should be 0.0..10.0
  481. color_correction_offset: u32le, // 0 if no color correction information
  482. postage_stamp_offset: u32le, // 0 if no thumbnail
  483. scanline_offset: u32le, // 0 if no scanline table
  484. attributes: TGA_Alpha_Kind,
  485. }
  486. #assert(size_of(TGA_Extension) == 495)
  487. TGA_Alpha_Kind :: enum u8 {
  488. None,
  489. Undefined_Ignore,
  490. Undefined_Retain,
  491. Useful,
  492. Premultiplied,
  493. }
  494. TGA_Info :: struct {
  495. header: TGA_Header,
  496. image_id: string,
  497. footer: Maybe(TGA_Footer),
  498. extension: Maybe(TGA_Extension),
  499. }
  500. /*
  501. JPEG-specific
  502. */
  503. JFIF_Magic := [?]byte{0x4A, 0x46, 0x49, 0x46} // "JFIF"
  504. JFXX_Magic := [?]byte{0x4A, 0x46, 0x58, 0x58} // "JFXX"
  505. Exif_Magic := [?]byte{0x45, 0x78, 0x69, 0x66} // "Exif"
  506. JPEG_Error :: enum {
  507. None = 0,
  508. Duplicate_SOI_Marker,
  509. Invalid_JFXX_Extension_Code,
  510. Encountered_SOS_Before_SOF,
  511. Invalid_Quantization_Table_Precision,
  512. Invalid_Quantization_Table_Index,
  513. Invalid_Huffman_Coefficient_Type,
  514. Invalid_Huffman_Table_Index,
  515. Unsupported_Frame_Type,
  516. Invalid_Frame_Bit_Depth_Combo,
  517. Invalid_Sampling_Factor,
  518. Unsupported_12_Bit_Depth,
  519. Multiple_SOS_Markers,
  520. Encountered_RST_Marker_Outside_ECS,
  521. Extra_Data_After_SOS, // Image seemed to have decoded okay, but there's more data after SOS
  522. Invalid_Thumbnail_Size,
  523. Huffman_Symbols_Exceeds_Max,
  524. }
  525. JFIF_Unit :: enum byte {
  526. None = 0,
  527. Dots_Per_Inch = 1,
  528. Dots_Per_Centimeter = 2,
  529. }
  530. JFIF_APP0 :: struct {
  531. version: u16be,
  532. x_density: u16be,
  533. y_density: u16be,
  534. units: JFIF_Unit,
  535. x_thumbnail: u8,
  536. y_thumbnail: u8,
  537. greyscale_thumbnail: bool,
  538. thumbnail: []RGB_Pixel `fmt:"-"`,
  539. }
  540. JFXX_APP0 :: struct {
  541. extension_code: JFXX_Extension_Code,
  542. x_thumbnail: u8,
  543. y_thumbnail: u8,
  544. thumbnail: []byte `fmt:"-"`,
  545. }
  546. JFXX_Extension_Code :: enum u8 {
  547. Thumbnail_JPEG = 0x10,
  548. Thumbnail_1_Byte_Palette = 0x11,
  549. Thumbnail_3_Byte_RGB = 0x13,
  550. }
  551. JPEG_Marker :: enum u8 {
  552. SOF0 = 0xC0, // Baseline sequential DCT
  553. SOF1 = 0xC1, // Extended sequential DCT
  554. SOF2 = 0xC2, // Progressive DCT
  555. SOF3 = 0xC3, // Lossless (sequential)
  556. SOF5 = 0xC5, // Differential sequential DCT
  557. SOF6 = 0xC6, // Differential progressive DCT
  558. SOF7 = 0xC7, // Differential lossless (sequential)
  559. SOF9 = 0xC9, // Extended sequential DCT, Arithmetic coding
  560. SOF10 = 0xCA, // Progressive DCT, Arithmetic coding
  561. SOF11 = 0xCB, // Lossless (sequential), Arithmetic coding
  562. SOF13 = 0xCD, // Differential sequential DCT, Arithmetic coding
  563. SOF14 = 0xCE, // Differential progressive DCT, Arithmetic coding
  564. SOF15 = 0xCF, // Differential lossless (sequential), Arithmetic coding
  565. DHT = 0xC4,
  566. JPG = 0xC8,
  567. DAC = 0xCC,
  568. RST0 = 0xD0,
  569. RST1 = 0xD1,
  570. RST2 = 0xD2,
  571. RST3 = 0xD3,
  572. RST4 = 0xD4,
  573. RST5 = 0xD5,
  574. RST6 = 0xD6,
  575. RST7 = 0xD7,
  576. SOI = 0xD8,
  577. EOI = 0xD9,
  578. SOS = 0xDA,
  579. DQT = 0xDB,
  580. DNL = 0xDC,
  581. DRI = 0xDD,
  582. DHP = 0xDE,
  583. EXP = 0xDF,
  584. APP0 = 0xE0,
  585. APP1 = 0xE1,
  586. APP2 = 0xE2,
  587. APP3 = 0xE3,
  588. APP4 = 0xE4,
  589. APP5 = 0xE5,
  590. APP6 = 0xE6,
  591. APP7 = 0xE7,
  592. APP8 = 0xE8,
  593. APP9 = 0xE9,
  594. APP10 = 0xEA,
  595. APP11 = 0xEB,
  596. APP12 = 0xEC,
  597. APP13 = 0xED,
  598. APP14 = 0xEE,
  599. APP15 = 0xEF,
  600. JPG0 = 0xF0,
  601. JPG1 = 0xF1,
  602. JPG2 = 0xF2,
  603. JPG3 = 0xF3,
  604. JPG4 = 0xF4,
  605. JPG5 = 0xF5,
  606. JPG6 = 0xF6,
  607. JPG7 = 0xF7,
  608. JPG8 = 0xF8,
  609. JPG9 = 0xF9,
  610. JPG10 = 0xFA,
  611. JPG11 = 0xFB,
  612. JPG12 = 0xFC,
  613. JPG13 = 0xFD,
  614. COM = 0xFE,
  615. TEM = 0x01,
  616. }
  617. JPEG_Info :: struct {
  618. jfif_app0: Maybe(JFIF_APP0),
  619. jfxx_app0: Maybe(JFXX_APP0),
  620. comments: [dynamic]string,
  621. exif: [dynamic]Exif,
  622. frame_type: JPEG_Marker,
  623. }
  624. // Function to help with image buffer calculations
  625. compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) {
  626. size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height
  627. return
  628. }
  629. Channel :: enum u8 {
  630. R = 1,
  631. G = 2,
  632. B = 3,
  633. A = 4,
  634. }
  635. // Take a slice of pixels (`[]RGBA_Pixel`, etc), and return an `Image`
  636. // Don't call `destroy` on the resulting `Image`. Instead, delete the original `pixels` slice.
  637. pixels_to_image :: proc(pixels: [][$N]$E, width: int, height: int) -> (img: Image, ok: bool) where E == u8 || E == u16, N >= 1, N <= 4 {
  638. if len(pixels) != width * height {
  639. return {}, false
  640. }
  641. img.height = height
  642. img.width = width
  643. img.depth = 8 when E == u8 else 16
  644. img.channels = N
  645. s := transmute(runtime.Raw_Slice)pixels
  646. d := runtime.Raw_Dynamic_Array{
  647. data = s.data,
  648. len = s.len * size_of(E) * N,
  649. cap = s.len * size_of(E) * N,
  650. allocator = runtime.nil_allocator(),
  651. }
  652. img.pixels = bytes.Buffer{
  653. buf = transmute([dynamic]u8)d,
  654. }
  655. return img, true
  656. }
  657. // When you have an RGB(A) image, but want a particular channel.
  658. return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok: bool) {
  659. // Were we actually given a valid image?
  660. if img == nil {
  661. return nil, false
  662. }
  663. ok = false
  664. t: bytes.Buffer
  665. idx := int(channel)
  666. if img.channels == 2 && idx == 4 {
  667. // Alpha requested, which in a two channel image is index 2: G.
  668. idx = 2
  669. }
  670. if idx > img.channels {
  671. return {}, false
  672. }
  673. switch img.depth {
  674. case 8:
  675. buffer_size := compute_buffer_size(img.width, img.height, 1, 8)
  676. t = bytes.Buffer{}
  677. resize(&t.buf, buffer_size)
  678. i := bytes.buffer_to_bytes(&img.pixels)
  679. o := bytes.buffer_to_bytes(&t)
  680. for len(i) > 0 {
  681. o[0] = i[idx]
  682. i = i[img.channels:]
  683. o = o[1:]
  684. }
  685. case 16:
  686. buffer_size := compute_buffer_size(img.width, img.height, 1, 16)
  687. t = bytes.Buffer{}
  688. resize(&t.buf, buffer_size)
  689. i := mem.slice_data_cast([]u16, img.pixels.buf[:])
  690. o := mem.slice_data_cast([]u16, t.buf[:])
  691. for len(i) > 0 {
  692. o[0] = i[idx]
  693. i = i[img.channels:]
  694. o = o[1:]
  695. }
  696. case 1, 2, 4:
  697. // We shouldn't see this case, as the loader already turns these into 8-bit.
  698. return {}, false
  699. }
  700. res = new(Image)
  701. res.width = img.width
  702. res.height = img.height
  703. res.channels = 1
  704. res.depth = img.depth
  705. res.pixels = t
  706. res.background = img.background
  707. res.metadata = img.metadata
  708. return res, true
  709. }
  710. // Does the image have 1 or 2 channels, a valid bit depth (8 or 16),
  711. // Is the pointer valid, are the dimensions valid?
  712. is_valid_grayscale_image :: proc(img: ^Image) -> (ok: bool) {
  713. // Were we actually given a valid image?
  714. if img == nil {
  715. return false
  716. }
  717. // Are we a Gray or Gray + Alpha image?
  718. if img.channels != 1 && img.channels != 2 {
  719. return false
  720. }
  721. // Do we have an acceptable bit depth?
  722. if img.depth != 8 && img.depth != 16 {
  723. return false
  724. }
  725. // This returns 0 if any of the inputs is zero.
  726. bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth)
  727. // If the dimensions are invalid or the buffer size doesn't match the image characteristics, bail.
  728. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  729. return false
  730. }
  731. return true
  732. }
  733. // Does the image have 3 or 4 channels, a valid bit depth (8 or 16),
  734. // Is the pointer valid, are the dimensions valid?
  735. is_valid_color_image :: proc(img: ^Image) -> (ok: bool) {
  736. // Were we actually given a valid image?
  737. if img == nil {
  738. return false
  739. }
  740. // Are we an RGB or RGBA image?
  741. if img.channels != 3 && img.channels != 4 {
  742. return false
  743. }
  744. // Do we have an acceptable bit depth?
  745. if img.depth != 8 && img.depth != 16 {
  746. return false
  747. }
  748. // This returns 0 if any of the inputs is zero.
  749. bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth)
  750. // If the dimensions are invalid or the buffer size doesn't match the image characteristics, bail.
  751. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  752. return false
  753. }
  754. return true
  755. }
  756. // Does the image have 1..4 channels, a valid bit depth (8 or 16),
  757. // Is the pointer valid, are the dimensions valid?
  758. is_valid_image :: proc(img: ^Image) -> (ok: bool) {
  759. // Were we actually given a valid image?
  760. if img == nil {
  761. return false
  762. }
  763. return is_valid_color_image(img) || is_valid_grayscale_image(img)
  764. }
  765. Alpha_Key :: union {
  766. GA_Pixel,
  767. RGBA_Pixel,
  768. GA_Pixel_16,
  769. RGBA_Pixel_16,
  770. }
  771. /*
  772. Add alpha channel if missing, in-place.
  773. Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
  774. Any other number of channels will be considered an error, returning `false` without modifying the image.
  775. If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha).
  776. If an image doesn't already have an alpha channel:
  777. If the optional `alpha_key` is provided, it will be resolved as follows:
  778. - For RGB, if pix = key.rgb -> pix = {0, 0, 0, key.a}
  779. - For Gray, if pix = key.r -> pix = {0, key.g}
  780. Otherwise, an opaque alpha channel will be added.
  781. */
  782. alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {
  783. context.allocator = allocator
  784. if !is_valid_image(img) {
  785. return false
  786. }
  787. // We should now have a valid Image with 1..4 channels. Do we already have alpha?
  788. if img.channels == 2 || img.channels == 4 {
  789. // We're done.
  790. return true
  791. }
  792. channels := img.channels + 1
  793. bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth)
  794. buf := bytes.Buffer{}
  795. // Can we allocate the return buffer?
  796. if resize(&buf.buf, bytes_wanted) != nil {
  797. delete(buf.buf)
  798. return false
  799. }
  800. switch img.depth {
  801. case 8:
  802. switch channels {
  803. case 2:
  804. // Turn Gray into Gray + Alpha
  805. inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:])
  806. out := mem.slice_data_cast([]GA_Pixel, buf.buf[:])
  807. if key, key_ok := alpha_key.(GA_Pixel); key_ok {
  808. // We have keyed alpha.
  809. o: GA_Pixel
  810. for p in inp {
  811. if p.r == key.r {
  812. o = GA_Pixel{0, key.g}
  813. } else {
  814. o = GA_Pixel{p.r, 255}
  815. }
  816. out[0] = o
  817. out = out[1:]
  818. }
  819. } else {
  820. // No keyed alpha, just make all pixels opaque.
  821. o := GA_Pixel{0, 255}
  822. for p in inp {
  823. o.r = p.r
  824. out[0] = o
  825. out = out[1:]
  826. }
  827. }
  828. case 4:
  829. // Turn RGB into RGBA
  830. inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
  831. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  832. if key, key_ok := alpha_key.(RGBA_Pixel); key_ok {
  833. // We have keyed alpha.
  834. o: RGBA_Pixel
  835. for p in inp {
  836. if p == key.rgb {
  837. o = RGBA_Pixel{0, 0, 0, key.a}
  838. } else {
  839. o = RGBA_Pixel{p.r, p.g, p.b, 255}
  840. }
  841. out[0] = o
  842. out = out[1:]
  843. }
  844. } else {
  845. // No keyed alpha, just make all pixels opaque.
  846. o := RGBA_Pixel{0, 0, 0, 255}
  847. for p in inp {
  848. o.rgb = p
  849. out[0] = o
  850. out = out[1:]
  851. }
  852. }
  853. case:
  854. // We shouldn't get here.
  855. unreachable()
  856. }
  857. case 16:
  858. switch channels {
  859. case 2:
  860. // Turn Gray into Gray + Alpha
  861. inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:])
  862. out := mem.slice_data_cast([]GA_Pixel_16, buf.buf[:])
  863. if key, key_ok := alpha_key.(GA_Pixel_16); key_ok {
  864. // We have keyed alpha.
  865. o: GA_Pixel_16
  866. for p in inp {
  867. if p.r == key.r {
  868. o = GA_Pixel_16{0, key.g}
  869. } else {
  870. o = GA_Pixel_16{p.r, 65535}
  871. }
  872. out[0] = o
  873. out = out[1:]
  874. }
  875. } else {
  876. // No keyed alpha, just make all pixels opaque.
  877. o := GA_Pixel_16{0, 65535}
  878. for p in inp {
  879. o.r = p.r
  880. out[0] = o
  881. out = out[1:]
  882. }
  883. }
  884. case 4:
  885. // Turn RGB into RGBA
  886. inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:])
  887. out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:])
  888. if key, key_ok := alpha_key.(RGBA_Pixel_16); key_ok {
  889. // We have keyed alpha.
  890. o: RGBA_Pixel_16
  891. for p in inp {
  892. if p == key.rgb {
  893. o = RGBA_Pixel_16{0, 0, 0, key.a}
  894. } else {
  895. o = RGBA_Pixel_16{p.r, p.g, p.b, 65535}
  896. }
  897. out[0] = o
  898. out = out[1:]
  899. }
  900. } else {
  901. // No keyed alpha, just make all pixels opaque.
  902. o := RGBA_Pixel_16{0, 0, 0, 65535}
  903. for p in inp {
  904. o.rgb = p
  905. out[0] = o
  906. out = out[1:]
  907. }
  908. }
  909. case:
  910. // We shouldn't get here.
  911. unreachable()
  912. }
  913. }
  914. // If we got here, that means we've now got a buffer with the alpha channel added.
  915. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  916. bytes.buffer_destroy(&img.pixels)
  917. img.pixels = buf
  918. img.channels = channels
  919. return true
  920. }
  921. alpha_apply_keyed_alpha :: alpha_add_if_missing
  922. /*
  923. Drop alpha channel if present, in-place.
  924. Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
  925. Any other number of channels will be considered an error, returning `false` without modifying the image.
  926. Of the `options`, the following are considered:
  927. `.alpha_premultiply`
  928. If the image has an alpha channel, returns image data as follows:
  929. RGB *= A, Gray = Gray *= A
  930. `.blend_background`
  931. If `img.background` is set, it'll be blended in like this:
  932. RGB = (1 - A) * Background + A * RGB
  933. If an image has 1 (Gray) or 3 (RGB) channels, it'll return early without modifying the image,
  934. with one exception: `alpha_key` and `img.background` are present, and `.blend_background` is set.
  935. In this case a keyed alpha pixel will be replaced with the background color.
  936. */
  937. alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {
  938. context.allocator = allocator
  939. if !is_valid_image(img) {
  940. return false
  941. }
  942. // Do we have a background to blend?
  943. will_it_blend := false
  944. switch v in img.background {
  945. case RGB_Pixel_16: will_it_blend = true if .blend_background in options else false
  946. }
  947. // Do we have keyed alpha?
  948. keyed := false
  949. switch v in alpha_key {
  950. case GA_Pixel: keyed = true if img.channels == 1 && img.depth == 8 else false
  951. case RGBA_Pixel: keyed = true if img.channels == 3 && img.depth == 8 else false
  952. case GA_Pixel_16: keyed = true if img.channels == 1 && img.depth == 16 else false
  953. case RGBA_Pixel_16: keyed = true if img.channels == 3 && img.depth == 16 else false
  954. }
  955. // We should now have a valid Image with 1..4 channels. Do we have alpha?
  956. if img.channels == 1 || img.channels == 3 {
  957. if !(will_it_blend && keyed) {
  958. // We're done
  959. return true
  960. }
  961. }
  962. // # of destination channels
  963. channels := 1 if img.channels < 3 else 3
  964. bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth)
  965. buf := bytes.Buffer{}
  966. // Can we allocate the return buffer?
  967. if resize(&buf.buf, bytes_wanted) != nil {
  968. delete(buf.buf)
  969. return false
  970. }
  971. switch img.depth {
  972. case 8:
  973. switch img.channels {
  974. case 1: // Gray to Gray, but we should have keyed alpha + background.
  975. inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:])
  976. out := mem.slice_data_cast([]G_Pixel, buf.buf[:])
  977. key := alpha_key.(GA_Pixel).r
  978. bg := G_Pixel{}
  979. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  980. // Background is RGB 16-bit, take just the red channel's topmost byte.
  981. bg.r = u8(temp_bg.r >> 8)
  982. }
  983. for p in inp {
  984. out[0] = bg if p.r == key else p
  985. out = out[1:]
  986. }
  987. case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background.
  988. inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:])
  989. out := mem.slice_data_cast([]G_Pixel, buf.buf[:])
  990. if will_it_blend {
  991. // Blend with background "color", then drop alpha.
  992. bg := f32(0.0)
  993. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  994. // Background is RGB 16-bit, take just the red channel's topmost byte.
  995. bg = f32(temp_bg.r >> 8)
  996. }
  997. for p in inp {
  998. a := f32(p.g) / 255.0
  999. c := ((1.0 - a) * bg + a * f32(p.r))
  1000. out[0].r = u8(c)
  1001. out = out[1:]
  1002. }
  1003. } else if .alpha_premultiply in options {
  1004. // Premultiply component with alpha, then drop alpha.
  1005. for p in inp {
  1006. a := f32(p.g) / 255.0
  1007. c := f32(p.r) * a
  1008. out[0].r = u8(c)
  1009. out = out[1:]
  1010. }
  1011. } else {
  1012. // Just drop alpha on the floor.
  1013. for p in inp {
  1014. out[0].r = p.r
  1015. out = out[1:]
  1016. }
  1017. }
  1018. case 3: // RGB to RGB, but we should have keyed alpha + background.
  1019. inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
  1020. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  1021. key := alpha_key.(RGBA_Pixel)
  1022. bg := RGB_Pixel{}
  1023. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  1024. // Background is RGB 16-bit, squash down to 8 bits.
  1025. bg = {u8(temp_bg.r >> 8), u8(temp_bg.g >> 8), u8(temp_bg.b >> 8)}
  1026. }
  1027. for p in inp {
  1028. out[0] = bg if p == key.rgb else p
  1029. out = out[1:]
  1030. }
  1031. case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply.
  1032. inp := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:])
  1033. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  1034. if will_it_blend {
  1035. // Blend with background "color", then drop alpha.
  1036. bg := [3]f32{}
  1037. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  1038. // Background is RGB 16-bit, take just the red channel's topmost byte.
  1039. bg = {f32(temp_bg.r >> 8), f32(temp_bg.g >> 8), f32(temp_bg.b >> 8)}
  1040. }
  1041. for p in inp {
  1042. a := f32(p.a) / 255.0
  1043. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  1044. c := ((1.0 - a) * bg + a * rgb)
  1045. out[0] = {u8(c.r), u8(c.g), u8(c.b)}
  1046. out = out[1:]
  1047. }
  1048. } else if .alpha_premultiply in options {
  1049. // Premultiply component with alpha, then drop alpha.
  1050. for p in inp {
  1051. a := f32(p.a) / 255.0
  1052. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  1053. c := rgb * a
  1054. out[0] = {u8(c.r), u8(c.g), u8(c.b)}
  1055. out = out[1:]
  1056. }
  1057. } else {
  1058. // Just drop alpha on the floor.
  1059. for p in inp {
  1060. out[0] = p.rgb
  1061. out = out[1:]
  1062. }
  1063. }
  1064. }
  1065. case 16:
  1066. switch img.channels {
  1067. case 1: // Gray to Gray, but we should have keyed alpha + background.
  1068. inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:])
  1069. out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:])
  1070. key := alpha_key.(GA_Pixel_16).r
  1071. bg := G_Pixel_16{}
  1072. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  1073. // Background is RGB 16-bit, take just the red channel.
  1074. bg.r = temp_bg.r
  1075. }
  1076. for p in inp {
  1077. out[0] = bg if p.r == key else p
  1078. out = out[1:]
  1079. }
  1080. case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background.
  1081. inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:])
  1082. out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:])
  1083. if will_it_blend {
  1084. // Blend with background "color", then drop alpha.
  1085. bg := f32(0.0)
  1086. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  1087. // Background is RGB 16-bit, take just the red channel.
  1088. bg = f32(temp_bg.r)
  1089. }
  1090. for p in inp {
  1091. a := f32(p.g) / 65535.0
  1092. c := ((1.0 - a) * bg + a * f32(p.r))
  1093. out[0].r = u16(c)
  1094. out = out[1:]
  1095. }
  1096. } else if .alpha_premultiply in options {
  1097. // Premultiply component with alpha, then drop alpha.
  1098. for p in inp {
  1099. a := f32(p.g) / 65535.0
  1100. c := f32(p.r) * a
  1101. out[0].r = u16(c)
  1102. out = out[1:]
  1103. }
  1104. } else {
  1105. // Just drop alpha on the floor.
  1106. for p in inp {
  1107. out[0].r = p.r
  1108. out = out[1:]
  1109. }
  1110. }
  1111. case 3: // RGB to RGB, but we should have keyed alpha + background.
  1112. inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:])
  1113. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  1114. key := alpha_key.(RGBA_Pixel_16)
  1115. bg := img.background.(RGB_Pixel_16)
  1116. for p in inp {
  1117. out[0] = bg if p == key.rgb else p
  1118. out = out[1:]
  1119. }
  1120. case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply.
  1121. inp := mem.slice_data_cast([]RGBA_Pixel_16, img.pixels.buf[:])
  1122. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  1123. if will_it_blend {
  1124. // Blend with background "color", then drop alpha.
  1125. bg := [3]f32{}
  1126. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  1127. // Background is RGB 16-bit, convert to [3]f32 to blend.
  1128. bg = {f32(temp_bg.r), f32(temp_bg.g), f32(temp_bg.b)}
  1129. }
  1130. for p in inp {
  1131. a := f32(p.a) / 65535.0
  1132. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  1133. c := ((1.0 - a) * bg + a * rgb)
  1134. out[0] = {u16(c.r), u16(c.g), u16(c.b)}
  1135. out = out[1:]
  1136. }
  1137. } else if .alpha_premultiply in options {
  1138. // Premultiply component with alpha, then drop alpha.
  1139. for p in inp {
  1140. a := f32(p.a) / 65535.0
  1141. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  1142. c := rgb * a
  1143. out[0] = {u16(c.r), u16(c.g), u16(c.b)}
  1144. out = out[1:]
  1145. }
  1146. } else {
  1147. // Just drop alpha on the floor.
  1148. for p in inp {
  1149. out[0] = p.rgb
  1150. out = out[1:]
  1151. }
  1152. }
  1153. }
  1154. case:
  1155. unreachable()
  1156. }
  1157. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  1158. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  1159. bytes.buffer_destroy(&img.pixels)
  1160. img.pixels = buf
  1161. img.channels = channels
  1162. return true
  1163. }
  1164. // Apply palette to 8-bit single-channel image and return an 8-bit RGB image, in-place.
  1165. // If the image given is not a valid 8-bit single channel image, the procedure will return `false` early.
  1166. apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := context.allocator) -> (ok: bool) {
  1167. context.allocator = allocator
  1168. if img == nil || img.channels != 1 || img.depth != 8 {
  1169. return false
  1170. }
  1171. bytes_expected := compute_buffer_size(img.width, img.height, 1, 8)
  1172. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  1173. return false
  1174. }
  1175. // Can we allocate the return buffer?
  1176. buf := bytes.Buffer{}
  1177. bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
  1178. if resize(&buf.buf, bytes_wanted) != nil {
  1179. delete(buf.buf)
  1180. return false
  1181. }
  1182. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  1183. // Apply the palette
  1184. for p, i in img.pixels.buf {
  1185. out[i] = palette[p]
  1186. }
  1187. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  1188. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  1189. bytes.buffer_destroy(&img.pixels)
  1190. img.pixels = buf
  1191. img.channels = 3
  1192. return true
  1193. }
  1194. // Apply palette to 8-bit single-channel image and return an 8-bit RGBA image, in-place.
  1195. // If the image given is not a valid 8-bit single channel image, the procedure will return `false` early.
  1196. apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := context.allocator) -> (ok: bool) {
  1197. context.allocator = allocator
  1198. if img == nil || img.channels != 1 || img.depth != 8 {
  1199. return false
  1200. }
  1201. bytes_expected := compute_buffer_size(img.width, img.height, 1, 8)
  1202. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  1203. return false
  1204. }
  1205. // Can we allocate the return buffer?
  1206. buf := bytes.Buffer{}
  1207. bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
  1208. if resize(&buf.buf, bytes_wanted) != nil {
  1209. delete(buf.buf)
  1210. return false
  1211. }
  1212. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  1213. // Apply the palette
  1214. for p, i in img.pixels.buf {
  1215. out[i] = palette[p]
  1216. }
  1217. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  1218. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  1219. bytes.buffer_destroy(&img.pixels)
  1220. img.pixels = buf
  1221. img.channels = 4
  1222. return true
  1223. }
  1224. apply_palette :: proc{apply_palette_rgb, apply_palette_rgba}
  1225. blend_single_channel :: #force_inline proc(fg, alpha, bg: $T) -> (res: T) where T == u8 || T == u16 {
  1226. MAX :: 256 when T == u8 else 65536
  1227. c := u32(fg) * (MAX - u32(alpha)) + u32(bg) * (1 + u32(alpha))
  1228. return T(c & (MAX - 1))
  1229. }
  1230. blend_pixel :: #force_inline proc(fg: [$N]$T, alpha: T, bg: [N]T) -> (res: [N]T) where (T == u8 || T == u16), N >= 1, N <= 4 {
  1231. MAX :: 256 when T == u8 else 65536
  1232. when N == 1 {
  1233. r := u32(fg.r) * (MAX - u32(alpha)) + u32(bg.r) * (1 + u32(alpha))
  1234. return {T(r & (MAX - 1))}
  1235. }
  1236. when N == 2 {
  1237. r := u32(fg.r) * (MAX - u32(alpha)) + u32(bg.r) * (1 + u32(alpha))
  1238. g := u32(fg.g) * (MAX - u32(alpha)) + u32(bg.g) * (1 + u32(alpha))
  1239. return {T(r & (MAX - 1)), T(g & (MAX - 1))}
  1240. }
  1241. when N == 3 || N == 4 {
  1242. r := u32(fg.r) * (MAX - u32(alpha)) + u32(bg.r) * (1 + u32(alpha))
  1243. g := u32(fg.g) * (MAX - u32(alpha)) + u32(bg.g) * (1 + u32(alpha))
  1244. b := u32(fg.b) * (MAX - u32(alpha)) + u32(bg.b) * (1 + u32(alpha))
  1245. when N == 3 {
  1246. return {T(r & (MAX - 1)), T(g & (MAX - 1)), T(b & (MAX - 1))}
  1247. } else {
  1248. return {T(r & (MAX - 1)), T(g & (MAX - 1)), T(b & (MAX - 1)), MAX - 1}
  1249. }
  1250. }
  1251. unreachable()
  1252. }
  1253. blend :: proc{blend_single_channel, blend_pixel}
  1254. // For all pixels of the image, multiplies R, G and B by Alpha. This is useful mainly for games rendering anti-aliased transparent sprites.
  1255. // Grayscale with alpha images are supported as well.
  1256. // Note that some image formats like QOI explicitly do NOT support premultiplied alpha, so you will end up with a non-standard file.
  1257. premultiply_alpha :: proc(img: ^Image) -> (ok: bool) {
  1258. switch {
  1259. case img.channels == 2 && img.depth == 8:
  1260. pixels := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:])
  1261. for &pixel in pixels {
  1262. pixel.r = u8(u32(pixel.r) * u32(pixel.g) / 0xFF)
  1263. }
  1264. return true
  1265. case img.channels == 2 && img.depth == 16:
  1266. pixels := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:])
  1267. for &pixel in pixels {
  1268. pixel.r = u16(u32(pixel.r) * u32(pixel.g) / 0xFFFF)
  1269. }
  1270. return true
  1271. case img.channels == 4 && img.depth == 8:
  1272. pixels := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:])
  1273. for &pixel in pixels {
  1274. pixel.r = u8(u32(pixel.r) * u32(pixel.a) / 0xFF)
  1275. pixel.g = u8(u32(pixel.g) * u32(pixel.a) / 0xFF)
  1276. pixel.b = u8(u32(pixel.b) * u32(pixel.a) / 0xFF)
  1277. }
  1278. return true
  1279. case img.channels == 4 && img.depth == 16:
  1280. pixels := mem.slice_data_cast([]RGBA_Pixel_16, img.pixels.buf[:])
  1281. for &pixel in pixels {
  1282. pixel.r = u16(u32(pixel.r) * u32(pixel.a) / 0xFFFF)
  1283. pixel.g = u16(u32(pixel.g) * u32(pixel.a) / 0xFFFF)
  1284. pixel.b = u16(u32(pixel.b) * u32(pixel.a) / 0xFFFF)
  1285. }
  1286. return true
  1287. case: return false
  1288. }
  1289. }
  1290. // Replicates grayscale values into RGB(A) 8- or 16-bit images as appropriate.
  1291. // Returns early with `false` if already an RGB(A) image.
  1292. expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bool) {
  1293. context.allocator = allocator
  1294. if !is_valid_grayscale_image(img) {
  1295. return false
  1296. }
  1297. // We should have 1 or 2 channels of 8- or 16 bits now. We need to turn that into 3 or 4.
  1298. // Can we allocate the return buffer?
  1299. buf := bytes.Buffer{}
  1300. bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
  1301. if resize(&buf.buf, bytes_wanted) != nil {
  1302. delete(buf.buf)
  1303. return false
  1304. }
  1305. switch img.depth {
  1306. case 8:
  1307. switch img.channels {
  1308. case 1: // Turn Gray into RGB
  1309. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  1310. for p in img.pixels.buf {
  1311. out[0] = p // Broadcast gray value into RGB components.
  1312. out = out[1:]
  1313. }
  1314. case 2: // Turn Gray + Alpha into RGBA
  1315. inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:])
  1316. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  1317. for p in inp {
  1318. out[0].rgb = p.r // Gray component.
  1319. out[0].a = p.g // Alpha component.
  1320. out = out[1:]
  1321. }
  1322. case:
  1323. unreachable()
  1324. }
  1325. case 16:
  1326. switch img.channels {
  1327. case 1: // Turn Gray into RGB
  1328. inp := mem.slice_data_cast([]u16, img.pixels.buf[:])
  1329. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  1330. for p in inp {
  1331. out[0] = p // Broadcast gray value into RGB components.
  1332. out = out[1:]
  1333. }
  1334. case 2: // Turn Gray + Alpha into RGBA
  1335. inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:])
  1336. out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:])
  1337. for p in inp {
  1338. out[0].rgb = p.r // Gray component.
  1339. out[0].a = p.g // Alpha component.
  1340. out = out[1:]
  1341. }
  1342. case:
  1343. unreachable()
  1344. }
  1345. case:
  1346. unreachable()
  1347. }
  1348. // If we got here, that means we've now got a buffer with the extra alpha channel.
  1349. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  1350. bytes.buffer_destroy(&img.pixels)
  1351. img.pixels = buf
  1352. img.channels += 2
  1353. return true
  1354. }
  1355. /*
  1356. Helper functions to read and write data from/to a Context, etc.
  1357. */
  1358. @(optimization_mode="favor_size")
  1359. read_data :: proc(z: $C, $T: typeid) -> (res: T, err: compress.General_Error) {
  1360. if r, e := compress.read_data(z, T); e != .None {
  1361. return {}, .Stream_Too_Short
  1362. } else {
  1363. return r, nil
  1364. }
  1365. }
  1366. @(optimization_mode="favor_size")
  1367. read_u8 :: proc(z: $C) -> (res: u8, err: compress.General_Error) {
  1368. if r, e := compress.read_u8(z); e != .None {
  1369. return {}, .Stream_Too_Short
  1370. } else {
  1371. return r, nil
  1372. }
  1373. }
  1374. write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Error) {
  1375. if len(data) == 0 {
  1376. return nil
  1377. } else if len(data) == 1 {
  1378. if bytes.buffer_write_byte(buf, data[0]) != nil {
  1379. return .Resize_Failed
  1380. }
  1381. } else if n, _ := bytes.buffer_write(buf, data); n != len(data) {
  1382. return .Resize_Failed
  1383. }
  1384. return nil
  1385. }