common.odin 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  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:compress"
  13. import "base:runtime"
  14. /*
  15. 67_108_864 pixels max by default.
  16. For QOI, the Worst case scenario means all pixels will be encoded as RGBA literals, costing 5 bytes each.
  17. This caps memory usage at 320 MiB.
  18. The tunable is limited to 4_294_836_225 pixels maximum, or 4 GiB per 8-bit channel.
  19. It is not advised to tune it this large.
  20. The 64 Megapixel default is considered to be a decent upper bound you won't run into in practice,
  21. except in very specific circumstances.
  22. */
  23. MAX_DIMENSIONS :: min(#config(MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535)
  24. // Color
  25. RGB_Pixel :: [3]u8
  26. RGBA_Pixel :: [4]u8
  27. RGB_Pixel_16 :: [3]u16
  28. RGBA_Pixel_16 :: [4]u16
  29. // Grayscale
  30. G_Pixel :: [1]u8
  31. GA_Pixel :: [2]u8
  32. G_Pixel_16 :: [1]u16
  33. GA_Pixel_16 :: [2]u16
  34. Image :: struct {
  35. width: int,
  36. height: int,
  37. channels: int,
  38. depth: int, // Channel depth in bits, typically 8 or 16
  39. pixels: bytes.Buffer `fmt:"-"`,
  40. /*
  41. Some image loaders/writers can return/take an optional background color.
  42. For convenience, we return them as u16 so we don't need to switch on the type
  43. in our viewer, and can just test against nil.
  44. */
  45. background: Maybe(RGB_Pixel_16),
  46. metadata: Image_Metadata,
  47. which: Which_File_Type,
  48. }
  49. Image_Metadata :: union #shared_nil {
  50. ^Netpbm_Info,
  51. ^PNG_Info,
  52. ^QOI_Info,
  53. ^TGA_Info,
  54. }
  55. /*
  56. IMPORTANT: `.do_not_expand_*` options currently skip handling of the `alpha_*` options,
  57. therefore Gray+Alpha will be returned as such even if you add `.alpha_drop_if_present`,
  58. and `.alpha_add_if_missing` and keyed transparency will likewise be ignored.
  59. The same goes for indexed images. This will be remedied in a near future update.
  60. */
  61. /*
  62. Image_Option:
  63. `.info`
  64. This option behaves as `.return_metadata` and `.do_not_decompress_image` and can be used
  65. to gather an image's dimensions and color information.
  66. `.return_header`
  67. Fill out img.metadata.header with the image's format-specific header struct.
  68. If we only care about the image specs, we can set `.return_header` +
  69. `.do_not_decompress_image`, or `.info`.
  70. `.return_metadata`
  71. Returns all chunks not needed to decode the data.
  72. It also returns the header as if `.return_header` was set.
  73. `.do_not_decompress_image`
  74. Skip decompressing IDAT chunk, defiltering and the rest.
  75. `.do_not_expand_grayscale`
  76. Do not turn grayscale (+ Alpha) images into RGB(A).
  77. Returns just the 1 or 2 channels present, although 1, 2 and 4 bit are still scaled to 8-bit.
  78. `.do_not_expand_indexed`
  79. Do not turn indexed (+ Alpha) images into RGB(A).
  80. Returns just the 1 or 2 (with `tRNS`) channels present.
  81. Make sure to use `return_metadata` to also return the palette chunk so you can recolor it yourself.
  82. `.do_not_expand_channels`
  83. Applies both `.do_not_expand_grayscale` and `.do_not_expand_indexed`.
  84. `.alpha_add_if_missing`
  85. If the image has no alpha channel, it'll add one set to max(type).
  86. Turns RGB into RGBA and Gray into Gray+Alpha
  87. `.alpha_drop_if_present`
  88. If the image has an alpha channel, drop it.
  89. You may want to use `.alpha_premultiply` in this case.
  90. NOTE: For PNG, this also skips handling of the tRNS chunk, if present,
  91. unless you select `alpha_premultiply`.
  92. In this case it'll premultiply the specified pixels in question only,
  93. as the others are implicitly fully opaque.
  94. `.alpha_premultiply`
  95. If the image has an alpha channel, returns image data as follows:
  96. RGB *= A, Gray = Gray *= A
  97. `.blend_background`
  98. If a bKGD chunk is present in a PNG, we normally just set `img.background`
  99. with its value and leave it up to the application to decide how to display the image,
  100. as per the PNG specification.
  101. With `.blend_background` selected, we blend the image against the background
  102. color. As this negates the use for an alpha channel, we'll drop it _unless_
  103. you also specify `.alpha_add_if_missing`.
  104. Options that don't apply to an image format will be ignored by their loader.
  105. */
  106. Option :: enum {
  107. // LOAD OPTIONS
  108. info = 0,
  109. do_not_decompress_image,
  110. return_header,
  111. return_metadata,
  112. alpha_add_if_missing, // Ignored for QOI. Always returns RGBA8.
  113. alpha_drop_if_present, // Unimplemented for QOI. Returns error.
  114. alpha_premultiply, // Unimplemented for QOI. Returns error.
  115. blend_background, // Ignored for non-PNG formats
  116. // Unimplemented
  117. do_not_expand_grayscale,
  118. do_not_expand_indexed,
  119. do_not_expand_channels,
  120. // SAVE OPTIONS
  121. qoi_all_channels_linear, // QOI, informative only. If not set, defaults to sRGB with linear alpha.
  122. }
  123. Options :: distinct bit_set[Option]
  124. Error :: union #shared_nil {
  125. General_Image_Error,
  126. Netpbm_Error,
  127. PNG_Error,
  128. QOI_Error,
  129. compress.Error,
  130. compress.General_Error,
  131. compress.Deflate_Error,
  132. compress.ZLIB_Error,
  133. runtime.Allocator_Error,
  134. }
  135. General_Image_Error :: enum {
  136. None = 0,
  137. Unsupported_Option,
  138. // File I/O
  139. Unable_To_Read_File,
  140. Unable_To_Write_File,
  141. // Invalid
  142. Unsupported_Format,
  143. Invalid_Signature,
  144. Invalid_Input_Image,
  145. Image_Dimensions_Too_Large,
  146. Invalid_Image_Dimensions,
  147. Invalid_Number_Of_Channels,
  148. Image_Does_Not_Adhere_to_Spec,
  149. Invalid_Image_Depth,
  150. Invalid_Bit_Depth,
  151. Invalid_Color_Space,
  152. // More data than pixels to decode into, for example.
  153. Corrupt,
  154. // Output buffer is the wrong size
  155. Invalid_Output,
  156. // Allocation
  157. Unable_To_Allocate_Or_Resize,
  158. }
  159. /*
  160. Netpbm-specific definitions
  161. */
  162. Netpbm_Format :: enum {
  163. P1, P2, P3, P4, P5, P6, P7, Pf, PF,
  164. }
  165. Netpbm_Header :: struct {
  166. format: Netpbm_Format,
  167. width: int,
  168. height: int,
  169. channels: int,
  170. depth: int,
  171. maxval: int,
  172. tupltype: string,
  173. scale: f32,
  174. little_endian: bool,
  175. }
  176. Netpbm_Info :: struct {
  177. header: Netpbm_Header,
  178. }
  179. Netpbm_Error :: enum {
  180. None = 0,
  181. // reading
  182. Invalid_Header_Token_Character,
  183. Incomplete_Header,
  184. Invalid_Header_Value,
  185. Duplicate_Header_Field,
  186. Buffer_Too_Small,
  187. Invalid_Buffer_ASCII_Token,
  188. Invalid_Buffer_Value,
  189. // writing
  190. Invalid_Format,
  191. }
  192. /*
  193. PNG-specific definitions
  194. */
  195. PNG_Error :: enum {
  196. None = 0,
  197. IHDR_Not_First_Chunk,
  198. IHDR_Corrupt,
  199. IDAT_Missing,
  200. IDAT_Must_Be_Contiguous,
  201. IDAT_Corrupt,
  202. IDAT_Size_Too_Large,
  203. PLTE_Encountered_Unexpectedly,
  204. PLTE_Invalid_Length,
  205. PLTE_Missing,
  206. TRNS_Encountered_Unexpectedly,
  207. TNRS_Invalid_Length,
  208. BKGD_Invalid_Length,
  209. Unknown_Color_Type,
  210. Invalid_Color_Bit_Depth_Combo,
  211. Unknown_Filter_Method,
  212. Unknown_Interlace_Method,
  213. Requested_Channel_Not_Present,
  214. Post_Processing_Error,
  215. Invalid_Chunk_Length,
  216. }
  217. PNG_Info :: struct {
  218. header: PNG_IHDR,
  219. chunks: [dynamic]PNG_Chunk,
  220. }
  221. PNG_Chunk_Header :: struct #packed {
  222. length: u32be,
  223. type: PNG_Chunk_Type,
  224. }
  225. PNG_Chunk :: struct #packed {
  226. header: PNG_Chunk_Header,
  227. data: []byte,
  228. crc: u32be,
  229. }
  230. PNG_Chunk_Type :: enum u32be {
  231. // IHDR must come first in a file
  232. IHDR = 'I' << 24 | 'H' << 16 | 'D' << 8 | 'R',
  233. // PLTE must precede the first IDAT chunk
  234. PLTE = 'P' << 24 | 'L' << 16 | 'T' << 8 | 'E',
  235. bKGD = 'b' << 24 | 'K' << 16 | 'G' << 8 | 'D',
  236. tRNS = 't' << 24 | 'R' << 16 | 'N' << 8 | 'S',
  237. IDAT = 'I' << 24 | 'D' << 16 | 'A' << 8 | 'T',
  238. iTXt = 'i' << 24 | 'T' << 16 | 'X' << 8 | 't',
  239. tEXt = 't' << 24 | 'E' << 16 | 'X' << 8 | 't',
  240. zTXt = 'z' << 24 | 'T' << 16 | 'X' << 8 | 't',
  241. iCCP = 'i' << 24 | 'C' << 16 | 'C' << 8 | 'P',
  242. pHYs = 'p' << 24 | 'H' << 16 | 'Y' << 8 | 's',
  243. gAMA = 'g' << 24 | 'A' << 16 | 'M' << 8 | 'A',
  244. tIME = 't' << 24 | 'I' << 16 | 'M' << 8 | 'E',
  245. sPLT = 's' << 24 | 'P' << 16 | 'L' << 8 | 'T',
  246. sRGB = 's' << 24 | 'R' << 16 | 'G' << 8 | 'B',
  247. hIST = 'h' << 24 | 'I' << 16 | 'S' << 8 | 'T',
  248. cHRM = 'c' << 24 | 'H' << 16 | 'R' << 8 | 'M',
  249. sBIT = 's' << 24 | 'B' << 16 | 'I' << 8 | 'T',
  250. /*
  251. eXIf tags are not part of the core spec, but have been ratified
  252. in v1.5.0 of the PNG Ext register.
  253. We will provide unprocessed chunks to the caller if `.return_metadata` is set.
  254. Applications are free to implement an Exif decoder.
  255. */
  256. eXIf = 'e' << 24 | 'X' << 16 | 'I' << 8 | 'f',
  257. // PNG files must end with IEND
  258. IEND = 'I' << 24 | 'E' << 16 | 'N' << 8 | 'D',
  259. /*
  260. XCode sometimes produces "PNG" files that don't adhere to the PNG spec.
  261. We recognize them only in order to avoid doing further work on them.
  262. Some tools like PNG Defry may be able to repair them, but we're not
  263. going to reward Apple for producing proprietary broken files purporting
  264. to be PNGs by supporting them.
  265. */
  266. iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T',
  267. CgBI = 'C' << 24 | 'g' << 16 | 'B' << 8 | 'I',
  268. }
  269. PNG_IHDR :: struct #packed {
  270. width: u32be,
  271. height: u32be,
  272. bit_depth: u8,
  273. color_type: PNG_Color_Type,
  274. compression_method: u8,
  275. filter_method: u8,
  276. interlace_method: PNG_Interlace_Method,
  277. }
  278. PNG_IHDR_SIZE :: size_of(PNG_IHDR)
  279. #assert (PNG_IHDR_SIZE == 13)
  280. PNG_Color_Value :: enum u8 {
  281. Paletted = 0, // 1 << 0 = 1
  282. Color = 1, // 1 << 1 = 2
  283. Alpha = 2, // 1 << 2 = 4
  284. }
  285. PNG_Color_Type :: distinct bit_set[PNG_Color_Value; u8]
  286. PNG_Interlace_Method :: enum u8 {
  287. None = 0,
  288. Adam7 = 1,
  289. }
  290. /*
  291. QOI-specific definitions
  292. */
  293. QOI_Error :: enum {
  294. None = 0,
  295. Missing_Or_Corrupt_Trailer, // Image seemed to have decoded okay, but trailer is missing or corrupt.
  296. }
  297. QOI_Magic :: u32be(0x716f6966) // "qoif"
  298. QOI_Color_Space :: enum u8 {
  299. sRGB = 0,
  300. Linear = 1,
  301. }
  302. QOI_Header :: struct #packed {
  303. magic: u32be,
  304. width: u32be,
  305. height: u32be,
  306. channels: u8,
  307. color_space: QOI_Color_Space,
  308. }
  309. #assert(size_of(QOI_Header) == 14)
  310. QOI_Info :: struct {
  311. header: QOI_Header,
  312. }
  313. TGA_Data_Type :: enum u8 {
  314. No_Image_Data = 0,
  315. Uncompressed_Color_Mapped = 1,
  316. Uncompressed_RGB = 2,
  317. Uncompressed_Black_White = 3,
  318. Compressed_Color_Mapped = 9,
  319. Compressed_RGB = 10,
  320. Compressed_Black_White = 11,
  321. }
  322. TGA_Header :: struct #packed {
  323. id_length: u8,
  324. color_map_type: u8,
  325. data_type_code: TGA_Data_Type,
  326. color_map_origin: u16le,
  327. color_map_length: u16le,
  328. color_map_depth: u8,
  329. origin: [2]u16le,
  330. dimensions: [2]u16le,
  331. bits_per_pixel: u8,
  332. image_descriptor: u8,
  333. }
  334. #assert(size_of(TGA_Header) == 18)
  335. New_TGA_Signature :: "TRUEVISION-XFILE.\x00"
  336. TGA_Footer :: struct #packed {
  337. extension_area_offset: u32le,
  338. developer_directory_offset: u32le,
  339. signature: [18]u8 `fmt:"s,0"`, // Should match signature if New TGA.
  340. }
  341. #assert(size_of(TGA_Footer) == 26)
  342. TGA_Extension :: struct #packed {
  343. extension_size: u16le, // Size of this struct. If not 495 bytes it means it's an unsupported version.
  344. author_name: [41]u8 `fmt:"s,0"`, // Author name, ASCII. Zero-terminated
  345. author_comments: [324]u8 `fmt:"s,0"`, // Author comments, formatted as 4 lines of 80 character lines, each zero terminated.
  346. datetime: struct {month, day, year, hour, minute, second: u16le},
  347. job_name: [41]u8 `fmt:"s,0"`, // Author name, ASCII. Zero-terminated
  348. job_time: struct {hour, minute, second: u16le},
  349. software_id: [41]u8 `fmt:"s,0"`, // Software ID name, ASCII. Zero-terminated
  350. software_version: struct #packed {
  351. number: u16le, // Version number * 100
  352. letter: u8 `fmt:"r"`, // " " if not used
  353. },
  354. key_color: [4]u8, // ARGB key color used at time of production
  355. aspect_ratio: [2]u16le, // Numerator / Denominator
  356. gamma: [2]u16le, // Numerator / Denominator, range should be 0.0..10.0
  357. color_correction_offset: u32le, // 0 if no color correction information
  358. postage_stamp_offset: u32le, // 0 if no thumbnail
  359. scanline_offset: u32le, // 0 if no scanline table
  360. attributes: TGA_Alpha_Kind,
  361. }
  362. #assert(size_of(TGA_Extension) == 495)
  363. TGA_Alpha_Kind :: enum u8 {
  364. None,
  365. Undefined_Ignore,
  366. Undefined_Retain,
  367. Useful,
  368. Premultiplied,
  369. }
  370. TGA_Info :: struct {
  371. header: TGA_Header,
  372. image_id: string,
  373. footer: Maybe(TGA_Footer),
  374. extension: Maybe(TGA_Extension),
  375. }
  376. // Function to help with image buffer calculations
  377. compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) {
  378. size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height
  379. return
  380. }
  381. Channel :: enum u8 {
  382. R = 1,
  383. G = 2,
  384. B = 3,
  385. A = 4,
  386. }
  387. // When you have an RGB(A) image, but want a particular channel.
  388. return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok: bool) {
  389. // Were we actually given a valid image?
  390. if img == nil {
  391. return nil, false
  392. }
  393. ok = false
  394. t: bytes.Buffer
  395. idx := int(channel)
  396. if img.channels == 2 && idx == 4 {
  397. // Alpha requested, which in a two channel image is index 2: G.
  398. idx = 2
  399. }
  400. if idx > img.channels {
  401. return {}, false
  402. }
  403. switch img.depth {
  404. case 8:
  405. buffer_size := compute_buffer_size(img.width, img.height, 1, 8)
  406. t = bytes.Buffer{}
  407. resize(&t.buf, buffer_size)
  408. i := bytes.buffer_to_bytes(&img.pixels)
  409. o := bytes.buffer_to_bytes(&t)
  410. for len(i) > 0 {
  411. o[0] = i[idx]
  412. i = i[img.channels:]
  413. o = o[1:]
  414. }
  415. case 16:
  416. buffer_size := compute_buffer_size(img.width, img.height, 1, 16)
  417. t = bytes.Buffer{}
  418. resize(&t.buf, buffer_size)
  419. i := mem.slice_data_cast([]u16, img.pixels.buf[:])
  420. o := mem.slice_data_cast([]u16, t.buf[:])
  421. for len(i) > 0 {
  422. o[0] = i[idx]
  423. i = i[img.channels:]
  424. o = o[1:]
  425. }
  426. case 1, 2, 4:
  427. // We shouldn't see this case, as the loader already turns these into 8-bit.
  428. return {}, false
  429. }
  430. res = new(Image)
  431. res.width = img.width
  432. res.height = img.height
  433. res.channels = 1
  434. res.depth = img.depth
  435. res.pixels = t
  436. res.background = img.background
  437. res.metadata = img.metadata
  438. return res, true
  439. }
  440. // Does the image have 1 or 2 channels, a valid bit depth (8 or 16),
  441. // Is the pointer valid, are the dimensions valid?
  442. is_valid_grayscale_image :: proc(img: ^Image) -> (ok: bool) {
  443. // Were we actually given a valid image?
  444. if img == nil {
  445. return false
  446. }
  447. // Are we a Gray or Gray + Alpha image?
  448. if img.channels != 1 && img.channels != 2 {
  449. return false
  450. }
  451. // Do we have an acceptable bit depth?
  452. if img.depth != 8 && img.depth != 16 {
  453. return false
  454. }
  455. // This returns 0 if any of the inputs is zero.
  456. bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth)
  457. // If the dimensions are invalid or the buffer size doesn't match the image characteristics, bail.
  458. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  459. return false
  460. }
  461. return true
  462. }
  463. // Does the image have 3 or 4 channels, a valid bit depth (8 or 16),
  464. // Is the pointer valid, are the dimensions valid?
  465. is_valid_color_image :: proc(img: ^Image) -> (ok: bool) {
  466. // Were we actually given a valid image?
  467. if img == nil {
  468. return false
  469. }
  470. // Are we an RGB or RGBA image?
  471. if img.channels != 3 && img.channels != 4 {
  472. return false
  473. }
  474. // Do we have an acceptable bit depth?
  475. if img.depth != 8 && img.depth != 16 {
  476. return false
  477. }
  478. // This returns 0 if any of the inputs is zero.
  479. bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth)
  480. // If the dimensions are invalid or the buffer size doesn't match the image characteristics, bail.
  481. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  482. return false
  483. }
  484. return true
  485. }
  486. // Does the image have 1..4 channels, a valid bit depth (8 or 16),
  487. // Is the pointer valid, are the dimensions valid?
  488. is_valid_image :: proc(img: ^Image) -> (ok: bool) {
  489. // Were we actually given a valid image?
  490. if img == nil {
  491. return false
  492. }
  493. return is_valid_color_image(img) || is_valid_grayscale_image(img)
  494. }
  495. Alpha_Key :: union {
  496. GA_Pixel,
  497. RGBA_Pixel,
  498. GA_Pixel_16,
  499. RGBA_Pixel_16,
  500. }
  501. /*
  502. Add alpha channel if missing, in-place.
  503. Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
  504. Any other number of channels will be considered an error, returning `false` without modifying the image.
  505. If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha).
  506. If an image doesn't already have an alpha channel:
  507. If the optional `alpha_key` is provided, it will be resolved as follows:
  508. - For RGB, if pix = key.rgb -> pix = {0, 0, 0, key.a}
  509. - For Gray, if pix = key.r -> pix = {0, key.g}
  510. Otherwise, an opaque alpha channel will be added.
  511. */
  512. alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {
  513. context.allocator = allocator
  514. if !is_valid_image(img) {
  515. return false
  516. }
  517. // We should now have a valid Image with 1..4 channels. Do we already have alpha?
  518. if img.channels == 2 || img.channels == 4 {
  519. // We're done.
  520. return true
  521. }
  522. channels := img.channels + 1
  523. bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth)
  524. buf := bytes.Buffer{}
  525. // Can we allocate the return buffer?
  526. if resize(&buf.buf, bytes_wanted) != nil {
  527. delete(buf.buf)
  528. return false
  529. }
  530. switch img.depth {
  531. case 8:
  532. switch channels {
  533. case 2:
  534. // Turn Gray into Gray + Alpha
  535. inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:])
  536. out := mem.slice_data_cast([]GA_Pixel, buf.buf[:])
  537. if key, key_ok := alpha_key.(GA_Pixel); key_ok {
  538. // We have keyed alpha.
  539. o: GA_Pixel
  540. for p in inp {
  541. if p == key.r {
  542. o = GA_Pixel{0, key.g}
  543. } else {
  544. o = GA_Pixel{p.r, 255}
  545. }
  546. out[0] = o
  547. out = out[1:]
  548. }
  549. } else {
  550. // No keyed alpha, just make all pixels opaque.
  551. o := GA_Pixel{0, 255}
  552. for p in inp {
  553. o.r = p.r
  554. out[0] = o
  555. out = out[1:]
  556. }
  557. }
  558. case 4:
  559. // Turn RGB into RGBA
  560. inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
  561. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  562. if key, key_ok := alpha_key.(RGBA_Pixel); key_ok {
  563. // We have keyed alpha.
  564. o: RGBA_Pixel
  565. for p in inp {
  566. if p == key.rgb {
  567. o = RGBA_Pixel{0, 0, 0, key.a}
  568. } else {
  569. o = RGBA_Pixel{p.r, p.g, p.b, 255}
  570. }
  571. out[0] = o
  572. out = out[1:]
  573. }
  574. } else {
  575. // No keyed alpha, just make all pixels opaque.
  576. o := RGBA_Pixel{0, 0, 0, 255}
  577. for p in inp {
  578. o.rgb = p
  579. out[0] = o
  580. out = out[1:]
  581. }
  582. }
  583. case:
  584. // We shouldn't get here.
  585. unreachable()
  586. }
  587. case 16:
  588. switch channels {
  589. case 2:
  590. // Turn Gray into Gray + Alpha
  591. inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:])
  592. out := mem.slice_data_cast([]GA_Pixel_16, buf.buf[:])
  593. if key, key_ok := alpha_key.(GA_Pixel_16); key_ok {
  594. // We have keyed alpha.
  595. o: GA_Pixel_16
  596. for p in inp {
  597. if p == key.r {
  598. o = GA_Pixel_16{0, key.g}
  599. } else {
  600. o = GA_Pixel_16{p.r, 65535}
  601. }
  602. out[0] = o
  603. out = out[1:]
  604. }
  605. } else {
  606. // No keyed alpha, just make all pixels opaque.
  607. o := GA_Pixel_16{0, 65535}
  608. for p in inp {
  609. o.r = p.r
  610. out[0] = o
  611. out = out[1:]
  612. }
  613. }
  614. case 4:
  615. // Turn RGB into RGBA
  616. inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:])
  617. out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:])
  618. if key, key_ok := alpha_key.(RGBA_Pixel_16); key_ok {
  619. // We have keyed alpha.
  620. o: RGBA_Pixel_16
  621. for p in inp {
  622. if p == key.rgb {
  623. o = RGBA_Pixel_16{0, 0, 0, key.a}
  624. } else {
  625. o = RGBA_Pixel_16{p.r, p.g, p.b, 65535}
  626. }
  627. out[0] = o
  628. out = out[1:]
  629. }
  630. } else {
  631. // No keyed alpha, just make all pixels opaque.
  632. o := RGBA_Pixel_16{0, 0, 0, 65535}
  633. for p in inp {
  634. o.rgb = p
  635. out[0] = o
  636. out = out[1:]
  637. }
  638. }
  639. case:
  640. // We shouldn't get here.
  641. unreachable()
  642. }
  643. }
  644. // If we got here, that means we've now got a buffer with the alpha channel added.
  645. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  646. bytes.buffer_destroy(&img.pixels)
  647. img.pixels = buf
  648. img.channels = channels
  649. return true
  650. }
  651. alpha_apply_keyed_alpha :: alpha_add_if_missing
  652. /*
  653. Drop alpha channel if present, in-place.
  654. Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
  655. Any other number of channels will be considered an error, returning `false` without modifying the image.
  656. Of the `options`, the following are considered:
  657. `.alpha_premultiply`
  658. If the image has an alpha channel, returns image data as follows:
  659. RGB *= A, Gray = Gray *= A
  660. `.blend_background`
  661. If `img.background` is set, it'll be blended in like this:
  662. RGB = (1 - A) * Background + A * RGB
  663. If an image has 1 (Gray) or 3 (RGB) channels, it'll return early without modifying the image,
  664. with one exception: `alpha_key` and `img.background` are present, and `.blend_background` is set.
  665. In this case a keyed alpha pixel will be replaced with the background color.
  666. */
  667. alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {
  668. context.allocator = allocator
  669. if !is_valid_image(img) {
  670. return false
  671. }
  672. // Do we have a background to blend?
  673. will_it_blend := false
  674. switch v in img.background {
  675. case RGB_Pixel_16: will_it_blend = true if .blend_background in options else false
  676. }
  677. // Do we have keyed alpha?
  678. keyed := false
  679. switch v in alpha_key {
  680. case GA_Pixel: keyed = true if img.channels == 1 && img.depth == 8 else false
  681. case RGBA_Pixel: keyed = true if img.channels == 3 && img.depth == 8 else false
  682. case GA_Pixel_16: keyed = true if img.channels == 1 && img.depth == 16 else false
  683. case RGBA_Pixel_16: keyed = true if img.channels == 3 && img.depth == 16 else false
  684. }
  685. // We should now have a valid Image with 1..4 channels. Do we have alpha?
  686. if img.channels == 1 || img.channels == 3 {
  687. if !(will_it_blend && keyed) {
  688. // We're done
  689. return true
  690. }
  691. }
  692. // # of destination channels
  693. channels := 1 if img.channels < 3 else 3
  694. bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth)
  695. buf := bytes.Buffer{}
  696. // Can we allocate the return buffer?
  697. if resize(&buf.buf, bytes_wanted) != nil {
  698. delete(buf.buf)
  699. return false
  700. }
  701. switch img.depth {
  702. case 8:
  703. switch img.channels {
  704. case 1: // Gray to Gray, but we should have keyed alpha + background.
  705. inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:])
  706. out := mem.slice_data_cast([]G_Pixel, buf.buf[:])
  707. key := alpha_key.(GA_Pixel).r
  708. bg := G_Pixel{}
  709. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  710. // Background is RGB 16-bit, take just the red channel's topmost byte.
  711. bg = u8(temp_bg.r >> 8)
  712. }
  713. for p in inp {
  714. out[0] = bg if p == key else p
  715. out = out[1:]
  716. }
  717. case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background.
  718. inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:])
  719. out := mem.slice_data_cast([]G_Pixel, buf.buf[:])
  720. if will_it_blend {
  721. // Blend with background "color", then drop alpha.
  722. bg := f32(0.0)
  723. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  724. // Background is RGB 16-bit, take just the red channel's topmost byte.
  725. bg = f32(temp_bg.r >> 8)
  726. }
  727. for p in inp {
  728. a := f32(p.g) / 255.0
  729. c := ((1.0 - a) * bg + a * f32(p.r))
  730. out[0] = u8(c)
  731. out = out[1:]
  732. }
  733. } else if .alpha_premultiply in options {
  734. // Premultiply component with alpha, then drop alpha.
  735. for p in inp {
  736. a := f32(p.g) / 255.0
  737. c := f32(p.r) * a
  738. out[0] = u8(c)
  739. out = out[1:]
  740. }
  741. } else {
  742. // Just drop alpha on the floor.
  743. for p in inp {
  744. out[0] = p.r
  745. out = out[1:]
  746. }
  747. }
  748. case 3: // RGB to RGB, but we should have keyed alpha + background.
  749. inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
  750. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  751. key := alpha_key.(RGBA_Pixel)
  752. bg := RGB_Pixel{}
  753. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  754. // Background is RGB 16-bit, squash down to 8 bits.
  755. bg = {u8(temp_bg.r >> 8), u8(temp_bg.g >> 8), u8(temp_bg.b >> 8)}
  756. }
  757. for p in inp {
  758. out[0] = bg if p == key.rgb else p
  759. out = out[1:]
  760. }
  761. case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply.
  762. inp := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:])
  763. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  764. if will_it_blend {
  765. // Blend with background "color", then drop alpha.
  766. bg := [3]f32{}
  767. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  768. // Background is RGB 16-bit, take just the red channel's topmost byte.
  769. bg = {f32(temp_bg.r >> 8), f32(temp_bg.g >> 8), f32(temp_bg.b >> 8)}
  770. }
  771. for p in inp {
  772. a := f32(p.a) / 255.0
  773. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  774. c := ((1.0 - a) * bg + a * rgb)
  775. out[0] = {u8(c.r), u8(c.g), u8(c.b)}
  776. out = out[1:]
  777. }
  778. } else if .alpha_premultiply in options {
  779. // Premultiply component with alpha, then drop alpha.
  780. for p in inp {
  781. a := f32(p.a) / 255.0
  782. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  783. c := rgb * a
  784. out[0] = {u8(c.r), u8(c.g), u8(c.b)}
  785. out = out[1:]
  786. }
  787. } else {
  788. // Just drop alpha on the floor.
  789. for p in inp {
  790. out[0] = p.rgb
  791. out = out[1:]
  792. }
  793. }
  794. }
  795. case 16:
  796. switch img.channels {
  797. case 1: // Gray to Gray, but we should have keyed alpha + background.
  798. inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:])
  799. out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:])
  800. key := alpha_key.(GA_Pixel_16).r
  801. bg := G_Pixel_16{}
  802. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  803. // Background is RGB 16-bit, take just the red channel.
  804. bg = temp_bg.r
  805. }
  806. for p in inp {
  807. out[0] = bg if p == key else p
  808. out = out[1:]
  809. }
  810. case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background.
  811. inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:])
  812. out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:])
  813. if will_it_blend {
  814. // Blend with background "color", then drop alpha.
  815. bg := f32(0.0)
  816. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  817. // Background is RGB 16-bit, take just the red channel.
  818. bg = f32(temp_bg.r)
  819. }
  820. for p in inp {
  821. a := f32(p.g) / 65535.0
  822. c := ((1.0 - a) * bg + a * f32(p.r))
  823. out[0] = u16(c)
  824. out = out[1:]
  825. }
  826. } else if .alpha_premultiply in options {
  827. // Premultiply component with alpha, then drop alpha.
  828. for p in inp {
  829. a := f32(p.g) / 65535.0
  830. c := f32(p.r) * a
  831. out[0] = u16(c)
  832. out = out[1:]
  833. }
  834. } else {
  835. // Just drop alpha on the floor.
  836. for p in inp {
  837. out[0] = p.r
  838. out = out[1:]
  839. }
  840. }
  841. case 3: // RGB to RGB, but we should have keyed alpha + background.
  842. inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:])
  843. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  844. key := alpha_key.(RGBA_Pixel_16)
  845. bg := img.background.(RGB_Pixel_16)
  846. for p in inp {
  847. out[0] = bg if p == key.rgb else p
  848. out = out[1:]
  849. }
  850. case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply.
  851. inp := mem.slice_data_cast([]RGBA_Pixel_16, img.pixels.buf[:])
  852. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  853. if will_it_blend {
  854. // Blend with background "color", then drop alpha.
  855. bg := [3]f32{}
  856. if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok {
  857. // Background is RGB 16-bit, convert to [3]f32 to blend.
  858. bg = {f32(temp_bg.r), f32(temp_bg.g), f32(temp_bg.b)}
  859. }
  860. for p in inp {
  861. a := f32(p.a) / 65535.0
  862. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  863. c := ((1.0 - a) * bg + a * rgb)
  864. out[0] = {u16(c.r), u16(c.g), u16(c.b)}
  865. out = out[1:]
  866. }
  867. } else if .alpha_premultiply in options {
  868. // Premultiply component with alpha, then drop alpha.
  869. for p in inp {
  870. a := f32(p.a) / 65535.0
  871. rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)}
  872. c := rgb * a
  873. out[0] = {u16(c.r), u16(c.g), u16(c.b)}
  874. out = out[1:]
  875. }
  876. } else {
  877. // Just drop alpha on the floor.
  878. for p in inp {
  879. out[0] = p.rgb
  880. out = out[1:]
  881. }
  882. }
  883. }
  884. case:
  885. unreachable()
  886. }
  887. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  888. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  889. bytes.buffer_destroy(&img.pixels)
  890. img.pixels = buf
  891. img.channels = channels
  892. return true
  893. }
  894. // Apply palette to 8-bit single-channel image and return an 8-bit RGB image, in-place.
  895. // If the image given is not a valid 8-bit single channel image, the procedure will return `false` early.
  896. apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := context.allocator) -> (ok: bool) {
  897. context.allocator = allocator
  898. if img == nil || img.channels != 1 || img.depth != 8 {
  899. return false
  900. }
  901. bytes_expected := compute_buffer_size(img.width, img.height, 1, 8)
  902. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  903. return false
  904. }
  905. // Can we allocate the return buffer?
  906. buf := bytes.Buffer{}
  907. bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
  908. if resize(&buf.buf, bytes_wanted) != nil {
  909. delete(buf.buf)
  910. return false
  911. }
  912. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  913. // Apply the palette
  914. for p, i in img.pixels.buf {
  915. out[i] = palette[p]
  916. }
  917. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  918. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  919. bytes.buffer_destroy(&img.pixels)
  920. img.pixels = buf
  921. img.channels = 3
  922. return true
  923. }
  924. // Apply palette to 8-bit single-channel image and return an 8-bit RGBA image, in-place.
  925. // If the image given is not a valid 8-bit single channel image, the procedure will return `false` early.
  926. apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := context.allocator) -> (ok: bool) {
  927. context.allocator = allocator
  928. if img == nil || img.channels != 1 || img.depth != 8 {
  929. return false
  930. }
  931. bytes_expected := compute_buffer_size(img.width, img.height, 1, 8)
  932. if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS {
  933. return false
  934. }
  935. // Can we allocate the return buffer?
  936. buf := bytes.Buffer{}
  937. bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
  938. if resize(&buf.buf, bytes_wanted) != nil {
  939. delete(buf.buf)
  940. return false
  941. }
  942. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  943. // Apply the palette
  944. for p, i in img.pixels.buf {
  945. out[i] = palette[p]
  946. }
  947. // If we got here, that means we've now got a buffer with the alpha channel dropped.
  948. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  949. bytes.buffer_destroy(&img.pixels)
  950. img.pixels = buf
  951. img.channels = 4
  952. return true
  953. }
  954. apply_palette :: proc{apply_palette_rgb, apply_palette_rgba}
  955. // Replicates grayscale values into RGB(A) 8- or 16-bit images as appropriate.
  956. // Returns early with `false` if already an RGB(A) image.
  957. expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bool) {
  958. context.allocator = allocator
  959. if !is_valid_grayscale_image(img) {
  960. return false
  961. }
  962. // We should have 1 or 2 channels of 8- or 16 bits now. We need to turn that into 3 or 4.
  963. // Can we allocate the return buffer?
  964. buf := bytes.Buffer{}
  965. bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
  966. if resize(&buf.buf, bytes_wanted) != nil {
  967. delete(buf.buf)
  968. return false
  969. }
  970. switch img.depth {
  971. case 8:
  972. switch img.channels {
  973. case 1: // Turn Gray into RGB
  974. out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:])
  975. for p in img.pixels.buf {
  976. out[0] = p // Broadcast gray value into RGB components.
  977. out = out[1:]
  978. }
  979. case 2: // Turn Gray + Alpha into RGBA
  980. inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:])
  981. out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:])
  982. for p in inp {
  983. out[0].rgb = p.r // Gray component.
  984. out[0].a = p.g // Alpha component.
  985. }
  986. case:
  987. unreachable()
  988. }
  989. case 16:
  990. switch img.channels {
  991. case 1: // Turn Gray into RGB
  992. inp := mem.slice_data_cast([]u16, img.pixels.buf[:])
  993. out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:])
  994. for p in inp {
  995. out[0] = p // Broadcast gray value into RGB components.
  996. out = out[1:]
  997. }
  998. case 2: // Turn Gray + Alpha into RGBA
  999. inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:])
  1000. out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:])
  1001. for p in inp {
  1002. out[0].rgb = p.r // Gray component.
  1003. out[0].a = p.g // Alpha component.
  1004. }
  1005. case:
  1006. unreachable()
  1007. }
  1008. case:
  1009. unreachable()
  1010. }
  1011. // If we got here, that means we've now got a buffer with the extra alpha channel.
  1012. // Destroy the old pixel buffer and replace it with the new one, and update the channel count.
  1013. bytes.buffer_destroy(&img.pixels)
  1014. img.pixels = buf
  1015. img.channels += 2
  1016. return true
  1017. }
  1018. /*
  1019. Helper functions to read and write data from/to a Context, etc.
  1020. */
  1021. @(optimization_mode="speed")
  1022. read_data :: proc(z: $C, $T: typeid) -> (res: T, err: compress.General_Error) {
  1023. if r, e := compress.read_data(z, T); e != .None {
  1024. return {}, .Stream_Too_Short
  1025. } else {
  1026. return r, nil
  1027. }
  1028. }
  1029. @(optimization_mode="speed")
  1030. read_u8 :: proc(z: $C) -> (res: u8, err: compress.General_Error) {
  1031. if r, e := compress.read_u8(z); e != .None {
  1032. return {}, .Stream_Too_Short
  1033. } else {
  1034. return r, nil
  1035. }
  1036. }
  1037. write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Error) {
  1038. if len(data) == 0 {
  1039. return nil
  1040. } else if len(data) == 1 {
  1041. if bytes.buffer_write_byte(buf, data[0]) != nil {
  1042. return .Resize_Failed
  1043. }
  1044. } else if n, _ := bytes.buffer_write(buf, data); n != len(data) {
  1045. return .Resize_Failed
  1046. }
  1047. return nil
  1048. }