png.odin 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660
  1. package png
  2. /*
  3. Copyright 2021 Jeroen van Rijn <[email protected]>.
  4. Made available under Odin's BSD-2 license.
  5. List of contributors:
  6. Jeroen van Rijn: Initial implementation.
  7. Ginger Bill: Cosmetic changes.
  8. */
  9. import "core:compress"
  10. import "core:compress/zlib"
  11. import "core:image"
  12. import "core:os"
  13. import "core:strings"
  14. import "core:hash"
  15. import "core:bytes"
  16. import "core:io"
  17. import "core:mem"
  18. import "core:intrinsics"
  19. Error :: compress.Error;
  20. E_General :: compress.General_Error;
  21. E_PNG :: image.Error;
  22. E_Deflate :: compress.Deflate_Error;
  23. Image :: image.Image;
  24. Options :: image.Options;
  25. Signature :: enum u64be {
  26. // 0x89504e470d0a1a0a
  27. PNG = 0x89 << 56 | 'P' << 48 | 'N' << 40 | 'G' << 32 | '\r' << 24 | '\n' << 16 | 0x1a << 8 | '\n',
  28. }
  29. Info :: struct {
  30. header: IHDR,
  31. chunks: [dynamic]Chunk,
  32. }
  33. Chunk_Header :: struct #packed {
  34. length: u32be,
  35. type: Chunk_Type,
  36. }
  37. Chunk :: struct #packed {
  38. header: Chunk_Header,
  39. data: []byte,
  40. crc: u32be,
  41. }
  42. Chunk_Type :: enum u32be {
  43. // IHDR must come first in a file
  44. IHDR = 'I' << 24 | 'H' << 16 | 'D' << 8 | 'R',
  45. // PLTE must precede the first IDAT chunk
  46. PLTE = 'P' << 24 | 'L' << 16 | 'T' << 8 | 'E',
  47. bKGD = 'b' << 24 | 'K' << 16 | 'G' << 8 | 'D',
  48. tRNS = 't' << 24 | 'R' << 16 | 'N' << 8 | 'S',
  49. IDAT = 'I' << 24 | 'D' << 16 | 'A' << 8 | 'T',
  50. iTXt = 'i' << 24 | 'T' << 16 | 'X' << 8 | 't',
  51. tEXt = 't' << 24 | 'E' << 16 | 'X' << 8 | 't',
  52. zTXt = 'z' << 24 | 'T' << 16 | 'X' << 8 | 't',
  53. iCCP = 'i' << 24 | 'C' << 16 | 'C' << 8 | 'P',
  54. pHYs = 'p' << 24 | 'H' << 16 | 'Y' << 8 | 's',
  55. gAMA = 'g' << 24 | 'A' << 16 | 'M' << 8 | 'A',
  56. tIME = 't' << 24 | 'I' << 16 | 'M' << 8 | 'E',
  57. sPLT = 's' << 24 | 'P' << 16 | 'L' << 8 | 'T',
  58. sRGB = 's' << 24 | 'R' << 16 | 'G' << 8 | 'B',
  59. hIST = 'h' << 24 | 'I' << 16 | 'S' << 8 | 'T',
  60. cHRM = 'c' << 24 | 'H' << 16 | 'R' << 8 | 'M',
  61. sBIT = 's' << 24 | 'B' << 16 | 'I' << 8 | 'T',
  62. /*
  63. eXIf tags are not part of the core spec, but have been ratified
  64. in v1.5.0 of the PNG Ext register.
  65. We will provide unprocessed chunks to the caller if `.return_metadata` is set.
  66. Applications are free to implement an Exif decoder.
  67. */
  68. eXIf = 'e' << 24 | 'X' << 16 | 'I' << 8 | 'f',
  69. // PNG files must end with IEND
  70. IEND = 'I' << 24 | 'E' << 16 | 'N' << 8 | 'D',
  71. /*
  72. XCode sometimes produces "PNG" files that don't adhere to the PNG spec.
  73. We recognize them only in order to avoid doing further work on them.
  74. Some tools like PNG Defry may be able to repair them, but we're not
  75. going to reward Apple for producing proprietary broken files purporting
  76. to be PNGs by supporting them.
  77. */
  78. iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T',
  79. CbGI = 'C' << 24 | 'b' << 16 | 'H' << 8 | 'I',
  80. }
  81. IHDR :: struct #packed {
  82. width: u32be,
  83. height: u32be,
  84. bit_depth: u8,
  85. color_type: Color_Type,
  86. compression_method: u8,
  87. filter_method: u8,
  88. interlace_method: Interlace_Method,
  89. }
  90. IHDR_SIZE :: size_of(IHDR);
  91. #assert (IHDR_SIZE == 13);
  92. Color_Value :: enum u8 {
  93. Paletted = 0, // 1 << 0 = 1
  94. Color = 1, // 1 << 1 = 2
  95. Alpha = 2, // 1 << 2 = 4
  96. }
  97. Color_Type :: distinct bit_set[Color_Value; u8];
  98. Interlace_Method :: enum u8 {
  99. None = 0,
  100. Adam7 = 1,
  101. }
  102. Row_Filter :: enum u8 {
  103. None = 0,
  104. Sub = 1,
  105. Up = 2,
  106. Average = 3,
  107. Paeth = 4,
  108. };
  109. PLTE_Entry :: [3]u8;
  110. PLTE :: struct #packed {
  111. entries: [256]PLTE_Entry,
  112. used: u16,
  113. }
  114. hIST :: struct #packed {
  115. entries: [256]u16,
  116. used: u16,
  117. }
  118. sPLT :: struct #packed {
  119. name: string,
  120. depth: u8,
  121. entries: union {
  122. [][4]u8,
  123. [][4]u16,
  124. },
  125. used: u16,
  126. }
  127. // Other chunks
  128. tIME :: struct #packed {
  129. year: u16be,
  130. month: u8,
  131. day: u8,
  132. hour: u8,
  133. minute: u8,
  134. second: u8,
  135. };
  136. #assert(size_of(tIME) == 7);
  137. CIE_1931_Raw :: struct #packed {
  138. x: u32be,
  139. y: u32be,
  140. }
  141. CIE_1931 :: struct #packed {
  142. x: f32,
  143. y: f32,
  144. }
  145. cHRM_Raw :: struct #packed {
  146. w: CIE_1931_Raw,
  147. r: CIE_1931_Raw,
  148. g: CIE_1931_Raw,
  149. b: CIE_1931_Raw,
  150. }
  151. #assert(size_of(cHRM_Raw) == 32);
  152. cHRM :: struct #packed {
  153. w: CIE_1931,
  154. r: CIE_1931,
  155. g: CIE_1931,
  156. b: CIE_1931,
  157. }
  158. #assert(size_of(cHRM) == 32);
  159. gAMA :: struct {
  160. gamma_100k: u32be, // Gamma * 100k
  161. };
  162. #assert(size_of(gAMA) == 4);
  163. pHYs :: struct #packed {
  164. ppu_x: u32be,
  165. ppu_y: u32be,
  166. unit: pHYs_Unit,
  167. };
  168. #assert(size_of(pHYs) == 9);
  169. pHYs_Unit :: enum u8 {
  170. Unknown = 0,
  171. Meter = 1,
  172. };
  173. Text :: struct {
  174. keyword: string,
  175. keyword_localized: string,
  176. language: string,
  177. text: string,
  178. };
  179. Exif :: struct {
  180. byte_order: enum {
  181. little_endian,
  182. big_endian,
  183. },
  184. data: []u8,
  185. }
  186. iCCP :: struct {
  187. name: string,
  188. profile: []u8,
  189. }
  190. sRGB_Rendering_Intent :: enum u8 {
  191. Perceptual = 0,
  192. Relative_colorimetric = 1,
  193. Saturation = 2,
  194. Absolute_colorimetric = 3,
  195. }
  196. sRGB :: struct #packed {
  197. intent: sRGB_Rendering_Intent,
  198. }
  199. ADAM7_X_ORIG := []int{ 0,4,0,2,0,1,0 };
  200. ADAM7_Y_ORIG := []int{ 0,0,4,0,2,0,1 };
  201. ADAM7_X_SPACING := []int{ 8,8,4,4,2,2,1 };
  202. ADAM7_Y_SPACING := []int{ 8,8,8,4,4,2,2 };
  203. // Implementation starts here
  204. read_chunk :: proc(ctx: ^compress.Context) -> (chunk: Chunk, err: Error) {
  205. ch, e := compress.read_data(ctx, Chunk_Header);
  206. if e != .None {
  207. return {}, E_General.Stream_Too_Short;
  208. }
  209. chunk.header = ch;
  210. chunk.data, e = compress.read_slice(ctx, int(ch.length));
  211. if e != .None {
  212. return {}, E_General.Stream_Too_Short;
  213. }
  214. // Compute CRC over chunk type + data
  215. type := (^[4]byte)(&ch.type)^;
  216. computed_crc := hash.crc32(type[:]);
  217. computed_crc = hash.crc32(chunk.data, computed_crc);
  218. crc, e3 := compress.read_data(ctx, u32be);
  219. if e3 != .None {
  220. return {}, E_General.Stream_Too_Short;
  221. }
  222. chunk.crc = crc;
  223. if chunk.crc != u32be(computed_crc) {
  224. return {}, E_General.Checksum_Failed;
  225. }
  226. return chunk, nil;
  227. }
  228. read_header :: proc(ctx: ^compress.Context) -> (IHDR, Error) {
  229. c, e := read_chunk(ctx);
  230. if e != nil {
  231. return {}, e;
  232. }
  233. header := (^IHDR)(raw_data(c.data))^;
  234. // Validate IHDR
  235. using header;
  236. if width == 0 || height == 0 {
  237. return {}, E_PNG.Invalid_Image_Dimensions;
  238. }
  239. if compression_method != 0 {
  240. return {}, E_General.Unknown_Compression_Method;
  241. }
  242. if filter_method != 0 {
  243. return {}, E_PNG.Unknown_Filter_Method;
  244. }
  245. if interlace_method != .None && interlace_method != .Adam7 {
  246. return {}, E_PNG.Unknown_Interlace_Method;
  247. }
  248. switch transmute(u8)color_type {
  249. case 0:
  250. /*
  251. Grayscale.
  252. Allowed bit depths: 1, 2, 4, 8 and 16.
  253. */
  254. allowed := false;
  255. for i in ([]u8{1, 2, 4, 8, 16}) {
  256. if bit_depth == i {
  257. allowed = true;
  258. break;
  259. }
  260. }
  261. if !allowed {
  262. return {}, E_PNG.Invalid_Color_Bit_Depth_Combo;
  263. }
  264. case 2, 4, 6:
  265. /*
  266. RGB, Grayscale+Alpha, RGBA.
  267. Allowed bit depths: 8 and 16
  268. */
  269. if bit_depth != 8 && bit_depth != 16 {
  270. return {}, E_PNG.Invalid_Color_Bit_Depth_Combo;
  271. }
  272. case 3:
  273. /*
  274. Paletted. PLTE chunk must appear.
  275. Allowed bit depths: 1, 2, 4 and 8.
  276. */
  277. allowed := false;
  278. for i in ([]u8{1, 2, 4, 8}) {
  279. if bit_depth == i {
  280. allowed = true;
  281. break;
  282. }
  283. }
  284. if !allowed {
  285. return {}, E_PNG.Invalid_Color_Bit_Depth_Combo;
  286. }
  287. case:
  288. return {}, E_PNG.Unknown_Color_Type;
  289. }
  290. return header, nil;
  291. }
  292. chunk_type_to_name :: proc(type: ^Chunk_Type) -> string {
  293. t := transmute(^u8)type;
  294. return strings.string_from_ptr(t, 4);
  295. }
  296. load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
  297. r := bytes.Reader{};
  298. bytes.reader_init(&r, slice);
  299. stream := bytes.reader_to_stream(&r);
  300. ctx := &compress.Context{
  301. input = stream,
  302. input_data = slice,
  303. input_fully_in_memory = true,
  304. };
  305. /*
  306. TODO: Add a flag to tell the PNG loader that the stream is backed by a slice.
  307. This way the stream reader could avoid the copy into the temp memory returned by it,
  308. and instead return a slice into the original memory that's already owned by the caller.
  309. */
  310. img, err = load_from_stream(ctx, options, allocator);
  311. return img, err;
  312. }
  313. load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
  314. data, ok := os.read_entire_file(filename, allocator);
  315. defer delete(data);
  316. if ok {
  317. img, err = load_from_slice(data, options, allocator);
  318. return;
  319. } else {
  320. img = new(Image);
  321. return img, E_General.File_Not_Found;
  322. }
  323. }
  324. load_from_stream :: proc(ctx: ^compress.Context, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
  325. options := options;
  326. if .info in options {
  327. options |= {.return_metadata, .do_not_decompress_image};
  328. options -= {.info};
  329. }
  330. if .alpha_drop_if_present in options && .alpha_add_if_missing in options {
  331. return {}, E_General.Incompatible_Options;
  332. }
  333. if .do_not_expand_channels in options {
  334. options |= {.do_not_expand_grayscale, .do_not_expand_indexed};
  335. }
  336. if img == nil {
  337. img = new(Image);
  338. }
  339. info := new(Info, context.allocator);
  340. img.metadata_ptr = info;
  341. img.metadata_type = typeid_of(Info);
  342. signature, io_error := compress.read_data(ctx, Signature);
  343. if io_error != .None || signature != .PNG {
  344. return img, E_PNG.Invalid_PNG_Signature;
  345. }
  346. idat: []u8;
  347. idat_b: bytes.Buffer;
  348. idat_length := u32be(0);
  349. defer bytes.buffer_destroy(&idat_b);
  350. c: Chunk;
  351. ch: Chunk_Header;
  352. e: io.Error;
  353. header: IHDR;
  354. info.chunks.allocator = context.temp_allocator;
  355. // State to ensure correct chunk ordering.
  356. seen_ihdr := false; first := true;
  357. seen_plte := false;
  358. seen_bkgd := false;
  359. seen_trns := false;
  360. seen_idat := false;
  361. seen_iend := false;
  362. _plte := PLTE{};
  363. trns := Chunk{};
  364. final_image_channels := 0;
  365. read_error: io.Error;
  366. // 12 bytes is the size of a chunk with a zero-length payload.
  367. for read_error == .None && !seen_iend {
  368. // Peek at next chunk's length and type.
  369. // TODO: Some streams may not provide seek/read_at
  370. ch, e = compress.peek_data(ctx, Chunk_Header);
  371. if e != .None {
  372. return img, E_General.Stream_Too_Short;
  373. }
  374. // name := chunk_type_to_name(&ch.type); // Only used for debug prints during development.
  375. #partial switch ch.type {
  376. case .IHDR:
  377. if seen_ihdr || !first {
  378. return {}, E_PNG.IHDR_Not_First_Chunk;
  379. }
  380. seen_ihdr = true;
  381. header, err = read_header(ctx);
  382. if err != nil {
  383. return img, err;
  384. }
  385. if .Paletted in header.color_type {
  386. // Color type 3
  387. img.channels = 1;
  388. final_image_channels = 3;
  389. img.depth = 8;
  390. } else if .Color in header.color_type {
  391. // Color image without a palette
  392. img.channels = 3;
  393. final_image_channels = 3;
  394. img.depth = int(header.bit_depth);
  395. } else {
  396. // Grayscale
  397. img.channels = 1;
  398. final_image_channels = 1;
  399. img.depth = int(header.bit_depth);
  400. }
  401. if .Alpha in header.color_type {
  402. img.channels += 1;
  403. final_image_channels += 1;
  404. }
  405. if img.channels == 0 || img.depth == 0 {
  406. return {}, E_PNG.IHDR_Corrupt;
  407. }
  408. img.width = int(header.width);
  409. img.height = int(header.height);
  410. using header;
  411. h := IHDR{
  412. width = width,
  413. height = height,
  414. bit_depth = bit_depth,
  415. color_type = color_type,
  416. compression_method = compression_method,
  417. filter_method = filter_method,
  418. interlace_method = interlace_method,
  419. };
  420. info.header = h;
  421. case .PLTE:
  422. seen_plte = true;
  423. // PLTE must appear before IDAT and can't appear for color types 0, 4.
  424. ct := transmute(u8)info.header.color_type;
  425. if seen_idat || ct == 0 || ct == 4 {
  426. return img, E_PNG.PLTE_Encountered_Unexpectedly;
  427. }
  428. c, err = read_chunk(ctx);
  429. if err != nil {
  430. return img, err;
  431. }
  432. if c.header.length % 3 != 0 || c.header.length > 768 {
  433. return img, E_PNG.PLTE_Invalid_Length;
  434. }
  435. plte_ok: bool;
  436. _plte, plte_ok = plte(c);
  437. if !plte_ok {
  438. return img, E_PNG.PLTE_Invalid_Length;
  439. }
  440. if .return_metadata in options {
  441. append(&info.chunks, c);
  442. }
  443. case .IDAT:
  444. // If we only want image metadata and don't want the pixel data, we can early out.
  445. if .return_metadata not_in options && .do_not_decompress_image in options {
  446. img.channels = final_image_channels;
  447. return img, nil;
  448. }
  449. // There must be at least 1 IDAT, contiguous if more.
  450. if seen_idat {
  451. return img, E_PNG.IDAT_Must_Be_Contiguous;
  452. }
  453. if idat_length > 0 {
  454. return img, E_PNG.IDAT_Must_Be_Contiguous;
  455. }
  456. next := ch.type;
  457. for next == .IDAT {
  458. c, err = read_chunk(ctx);
  459. if err != nil {
  460. return img, err;
  461. }
  462. bytes.buffer_write(&idat_b, c.data);
  463. idat_length += c.header.length;
  464. ch, e = compress.peek_data(ctx, Chunk_Header);
  465. if e != .None {
  466. return img, E_General.Stream_Too_Short;
  467. }
  468. next = ch.type;
  469. }
  470. idat = bytes.buffer_to_bytes(&idat_b);
  471. if int(idat_length) != len(idat) {
  472. return {}, E_PNG.IDAT_Corrupt;
  473. }
  474. seen_idat = true;
  475. case .IEND:
  476. c, err = read_chunk(ctx);
  477. if err != nil {
  478. return img, err;
  479. }
  480. seen_iend = true;
  481. case .bKGD:
  482. // TODO: Make sure that 16-bit bKGD + tRNS chunks return u16 instead of u16be
  483. c, err = read_chunk(ctx);
  484. if err != nil {
  485. return img, err;
  486. }
  487. seen_bkgd = true;
  488. if .return_metadata in options {
  489. append(&info.chunks, c);
  490. }
  491. ct := transmute(u8)info.header.color_type;
  492. switch ct {
  493. case 3: // Indexed color
  494. if c.header.length != 1 {
  495. return {}, E_PNG.BKGD_Invalid_Length;
  496. }
  497. col := _plte.entries[c.data[0]];
  498. img.background = [3]u16{
  499. u16(col[0]) << 8 | u16(col[0]),
  500. u16(col[1]) << 8 | u16(col[1]),
  501. u16(col[2]) << 8 | u16(col[2]),
  502. };
  503. case 0, 4: // Grayscale, with and without Alpha
  504. if c.header.length != 2 {
  505. return {}, E_PNG.BKGD_Invalid_Length;
  506. }
  507. col := u16(mem.slice_data_cast([]u16be, c.data[:])[0]);
  508. img.background = [3]u16{col, col, col};
  509. case 2, 6: // Color, with and without Alpha
  510. if c.header.length != 6 {
  511. return {}, E_PNG.BKGD_Invalid_Length;
  512. }
  513. col := mem.slice_data_cast([]u16be, c.data[:]);
  514. img.background = [3]u16{u16(col[0]), u16(col[1]), u16(col[2])};
  515. }
  516. case .tRNS:
  517. c, err = read_chunk(ctx);
  518. if err != nil {
  519. return img, err;
  520. }
  521. if .Alpha in info.header.color_type {
  522. return img, E_PNG.TRNS_Encountered_Unexpectedly;
  523. }
  524. if .return_metadata in options {
  525. append(&info.chunks, c);
  526. }
  527. /*
  528. This makes the image one with transparency, so set it to +1 here,
  529. even if we need we leave img.channels alone for the defilterer's
  530. sake. If we early because the user just cares about metadata,
  531. we'll set it to 'final_image_channels'.
  532. */
  533. final_image_channels += 1;
  534. seen_trns = true;
  535. if info.header.bit_depth < 8 && .Paletted not_in info.header.color_type {
  536. // Rescale tRNS data so key matches intensity
  537. dsc := depth_scale_table;
  538. scale := dsc[info.header.bit_depth];
  539. if scale != 1 {
  540. key := mem.slice_data_cast([]u16be, c.data)[0] * u16be(scale);
  541. c.data = []u8{0, u8(key & 255)};
  542. }
  543. }
  544. trns = c;
  545. case .iDOT, .CbGI:
  546. /*
  547. iPhone PNG bastardization that doesn't adhere to spec with broken IDAT chunk.
  548. We're not going to add support for it. If you have the misfortunte of coming
  549. across one of these files, use a utility to defry it.s
  550. */
  551. return img, E_PNG.PNG_Does_Not_Adhere_to_Spec;
  552. case:
  553. // Unhandled type
  554. c, err = read_chunk(ctx);
  555. if err != nil {
  556. return img, err;
  557. }
  558. if .return_metadata in options {
  559. // NOTE: Chunk cata is currently allocated on the temp allocator.
  560. append(&info.chunks, c);
  561. }
  562. first = false;
  563. }
  564. }
  565. if .do_not_decompress_image in options {
  566. img.channels = final_image_channels;
  567. return img, nil;
  568. }
  569. if !seen_idat {
  570. return img, E_PNG.IDAT_Missing;
  571. }
  572. buf: bytes.Buffer;
  573. zlib_error := zlib.inflate(idat, &buf);
  574. defer bytes.buffer_destroy(&buf);
  575. if zlib_error != nil {
  576. return {}, zlib_error;
  577. } else {
  578. /*
  579. Let's calcalate the expected size of the IDAT based on its dimensions,
  580. and whether or not it's interlaced
  581. */
  582. expected_size: int;
  583. buf_len := len(buf.buf);
  584. if header.interlace_method != .Adam7 {
  585. expected_size = compute_buffer_size(int(header.width), int(header.height), int(img.channels), int(header.bit_depth), 1);
  586. } else {
  587. /*
  588. Because Adam7 divides the image up into sub-images, and each scanline must start
  589. with a filter byte, Adam7 interlaced images can have a larger raw size.
  590. */
  591. for p := 0; p < 7; p += 1 {
  592. x := (int(header.width) - ADAM7_X_ORIG[p] + ADAM7_X_SPACING[p] - 1) / ADAM7_X_SPACING[p];
  593. y := (int(header.height) - ADAM7_Y_ORIG[p] + ADAM7_Y_SPACING[p] - 1) / ADAM7_Y_SPACING[p];
  594. if x > 0 && y > 0 {
  595. expected_size += compute_buffer_size(int(x), int(y), int(img.channels), int(header.bit_depth), 1);
  596. }
  597. }
  598. }
  599. if expected_size != buf_len {
  600. return {}, E_PNG.IDAT_Corrupt;
  601. }
  602. }
  603. /*
  604. Defilter just cares about the raw number of image channels present.
  605. So, we'll save the old value of img.channels we return to the user
  606. as metadata, and set it instead to the raw number of channels.
  607. */
  608. defilter_error := defilter(img, &buf, &header, options);
  609. if defilter_error != nil {
  610. bytes.buffer_destroy(&img.pixels);
  611. return {}, defilter_error;
  612. }
  613. /*
  614. Now we'll handle the relocoring of paletted images, handling of tRNS chunks,
  615. and we'll expand grayscale images to RGB(A).
  616. For the sake of convenience we return only RGB(A) images. In the future we
  617. may supply an option to return Gray/Gray+Alpha as-is, in which case RGB(A)
  618. will become the default.
  619. */
  620. if .Paletted in header.color_type && .do_not_expand_indexed in options {
  621. return img, nil;
  622. }
  623. if .Color not_in header.color_type && .do_not_expand_grayscale in options {
  624. return img, nil;
  625. }
  626. raw_image_channels := img.channels;
  627. out_image_channels := 3;
  628. /*
  629. To give ourselves less options to test, we'll knock out
  630. `.blend_background` and `seen_bkgd` if we haven't seen both.
  631. */
  632. if !(seen_bkgd && .blend_background in options) {
  633. options -= {.blend_background};
  634. seen_bkgd = false;
  635. }
  636. if seen_trns || .Alpha in info.header.color_type || .alpha_add_if_missing in options {
  637. out_image_channels = 4;
  638. }
  639. if .alpha_drop_if_present in options {
  640. out_image_channels = 3;
  641. }
  642. if seen_bkgd && .blend_background in options && .alpha_add_if_missing not_in options {
  643. out_image_channels = 3;
  644. }
  645. add_alpha := (seen_trns && .alpha_drop_if_present not_in options) || (.alpha_add_if_missing in options);
  646. premultiply := .alpha_premultiply in options || seen_bkgd;
  647. img.channels = out_image_channels;
  648. if .Paletted in header.color_type {
  649. temp := img.pixels;
  650. defer bytes.buffer_destroy(&temp);
  651. // We need to create a new image buffer
  652. dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8);
  653. t := bytes.Buffer{};
  654. resize(&t.buf, dest_raw_size);
  655. i := 0; j := 0;
  656. // If we don't have transparency or drop it without applying it, we can do this:
  657. if (!seen_trns || (seen_trns && .alpha_drop_if_present in options && .alpha_premultiply not_in options)) && .alpha_add_if_missing not_in options {
  658. for h := 0; h < int(img.height); h += 1 {
  659. for w := 0; w < int(img.width); w += 1 {
  660. c := _plte.entries[temp.buf[i]];
  661. t.buf[j ] = c.r;
  662. t.buf[j+1] = c.g;
  663. t.buf[j+2] = c.b;
  664. i += 1; j += 3;
  665. }
  666. }
  667. } else if add_alpha || .alpha_drop_if_present in options {
  668. bg := [3]f32{0, 0, 0};
  669. if premultiply && seen_bkgd {
  670. c16 := img.background.([3]u16);
  671. bg = [3]f32{f32(c16.r), f32(c16.g), f32(c16.b)};
  672. }
  673. no_alpha := (.alpha_drop_if_present in options || premultiply) && .alpha_add_if_missing not_in options;
  674. blend_background := seen_bkgd && .blend_background in options;
  675. for h := 0; h < int(img.height); h += 1 {
  676. for w := 0; w < int(img.width); w += 1 {
  677. index := temp.buf[i];
  678. c := _plte.entries[index];
  679. a := int(index) < len(trns.data) ? trns.data[index] : 255;
  680. alpha := f32(a) / 255.0;
  681. if blend_background {
  682. c.r = u8((1.0 - alpha) * bg[0] + f32(c.r) * alpha);
  683. c.g = u8((1.0 - alpha) * bg[1] + f32(c.g) * alpha);
  684. c.b = u8((1.0 - alpha) * bg[2] + f32(c.b) * alpha);
  685. a = 255;
  686. } else if premultiply {
  687. c.r = u8(f32(c.r) * alpha);
  688. c.g = u8(f32(c.g) * alpha);
  689. c.b = u8(f32(c.b) * alpha);
  690. }
  691. t.buf[j ] = c.r;
  692. t.buf[j+1] = c.g;
  693. t.buf[j+2] = c.b;
  694. i += 1;
  695. if no_alpha {
  696. j += 3;
  697. } else {
  698. t.buf[j+3] = u8(a);
  699. j += 4;
  700. }
  701. }
  702. }
  703. } else {
  704. unreachable();
  705. }
  706. img.pixels = t;
  707. } else if img.depth == 16 {
  708. // Check if we need to do something.
  709. if raw_image_channels == out_image_channels {
  710. // If we have 3 in and 3 out, or 4 in and 4 out without premultiplication...
  711. if raw_image_channels == 4 && .alpha_premultiply not_in options && !seen_bkgd {
  712. // Then we're done.
  713. return img, nil;
  714. }
  715. }
  716. temp := img.pixels;
  717. defer bytes.buffer_destroy(&temp);
  718. // We need to create a new image buffer
  719. dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16);
  720. t := bytes.Buffer{};
  721. resize(&t.buf, dest_raw_size);
  722. p16 := mem.slice_data_cast([]u16, temp.buf[:]);
  723. o16 := mem.slice_data_cast([]u16, t.buf[:]);
  724. switch raw_image_channels {
  725. case 1:
  726. // Gray without Alpha. Might have tRNS alpha.
  727. key := u16(0);
  728. if seen_trns {
  729. key = mem.slice_data_cast([]u16, trns.data)[0];
  730. }
  731. for len(p16) > 0 {
  732. r := p16[0];
  733. alpha := u16(1); // Default to full opaque
  734. if seen_trns {
  735. if r == key {
  736. if seen_bkgd {
  737. c := img.background.([3]u16);
  738. r = c[0];
  739. } else {
  740. alpha = 0; // Keyed transparency
  741. }
  742. }
  743. }
  744. if premultiply {
  745. o16[0] = r * alpha;
  746. o16[1] = r * alpha;
  747. o16[2] = r * alpha;
  748. } else {
  749. o16[0] = r;
  750. o16[1] = r;
  751. o16[2] = r;
  752. }
  753. if out_image_channels == 4 {
  754. o16[3] = alpha * 65535;
  755. }
  756. p16 = p16[1:];
  757. o16 = o16[out_image_channels:];
  758. }
  759. case 2:
  760. // Gray with alpha, we shouldn't have a tRNS chunk.
  761. bg := f32(0.0);
  762. if seen_bkgd {
  763. bg = f32(img.background.([3]u16)[0]);
  764. }
  765. for len(p16) > 0 {
  766. r := p16[0];
  767. if seen_bkgd {
  768. alpha := f32(p16[1]) / f32(65535);
  769. c := u16(f32(r) * alpha + (1.0 - alpha) * bg);
  770. o16[0] = c;
  771. o16[1] = c;
  772. o16[2] = c;
  773. /*
  774. After BG blending, the pixel is now fully opaque.
  775. Update the value we'll write to the output alpha.
  776. */
  777. p16[1] = 65535;
  778. } else if premultiply {
  779. alpha := p16[1];
  780. c := u16(f32(r) * f32(alpha) / f32(65535));
  781. o16[0] = c;
  782. o16[1] = c;
  783. o16[2] = c;
  784. } else {
  785. o16[0] = r;
  786. o16[1] = r;
  787. o16[2] = r;
  788. }
  789. if out_image_channels == 4 {
  790. o16[3] = p16[1];
  791. }
  792. p16 = p16[2:];
  793. o16 = o16[out_image_channels:];
  794. }
  795. case 3:
  796. /*
  797. Color without Alpha.
  798. We may still have a tRNS chunk or `.alpha_add_if_missing`.
  799. */
  800. key: []u16;
  801. if seen_trns {
  802. key = mem.slice_data_cast([]u16, trns.data);
  803. }
  804. for len(p16) > 0 {
  805. r := p16[0];
  806. g := p16[1];
  807. b := p16[2];
  808. alpha := u16(1); // Default to full opaque
  809. if seen_trns {
  810. if r == key[0] && g == key[1] && b == key[2] {
  811. if seen_bkgd {
  812. c := img.background.([3]u16);
  813. r = c[0];
  814. g = c[1];
  815. b = c[2];
  816. } else {
  817. alpha = 0; // Keyed transparency
  818. }
  819. }
  820. }
  821. if premultiply {
  822. o16[0] = r * alpha;
  823. o16[1] = g * alpha;
  824. o16[2] = b * alpha;
  825. } else {
  826. o16[0] = r;
  827. o16[1] = g;
  828. o16[2] = b;
  829. }
  830. if out_image_channels == 4 {
  831. o16[3] = alpha * 65535;
  832. }
  833. p16 = p16[3:];
  834. o16 = o16[out_image_channels:];
  835. }
  836. case 4:
  837. // Color with Alpha, can't have tRNS.
  838. for len(p16) > 0 {
  839. r := p16[0];
  840. g := p16[1];
  841. b := p16[2];
  842. a := p16[3];
  843. if seen_bkgd {
  844. alpha := f32(a) / 65535.0;
  845. c := img.background.([3]u16);
  846. rb := f32(c[0]) * (1.0 - alpha);
  847. gb := f32(c[1]) * (1.0 - alpha);
  848. bb := f32(c[2]) * (1.0 - alpha);
  849. o16[0] = u16(f32(r) * alpha + rb);
  850. o16[1] = u16(f32(g) * alpha + gb);
  851. o16[2] = u16(f32(b) * alpha + bb);
  852. /*
  853. After BG blending, the pixel is now fully opaque.
  854. Update the value we'll write to the output alpha.
  855. */
  856. a = 65535;
  857. } else if premultiply {
  858. alpha := f32(a) / 65535.0;
  859. o16[0] = u16(f32(r) * alpha);
  860. o16[1] = u16(f32(g) * alpha);
  861. o16[2] = u16(f32(b) * alpha);
  862. } else {
  863. o16[0] = r;
  864. o16[1] = g;
  865. o16[2] = b;
  866. }
  867. if out_image_channels == 4 {
  868. o16[3] = a;
  869. }
  870. p16 = p16[4:];
  871. o16 = o16[out_image_channels:];
  872. }
  873. case:
  874. unreachable("We should never seen # channels other than 1-4 inclusive.");
  875. }
  876. img.pixels = t;
  877. img.channels = out_image_channels;
  878. } else if img.depth == 8 {
  879. // Check if we need to do something.
  880. if raw_image_channels == out_image_channels {
  881. // If we have 3 in and 3 out, or 4 in and 4 out without premultiplication...
  882. if !premultiply {
  883. // Then we're done.
  884. return img, nil;
  885. }
  886. }
  887. temp := img.pixels;
  888. defer bytes.buffer_destroy(&temp);
  889. // We need to create a new image buffer
  890. dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8);
  891. t := bytes.Buffer{};
  892. resize(&t.buf, dest_raw_size);
  893. p := mem.slice_data_cast([]u8, temp.buf[:]);
  894. o := mem.slice_data_cast([]u8, t.buf[:]);
  895. switch raw_image_channels {
  896. case 1:
  897. // Gray without Alpha. Might have tRNS alpha.
  898. key := u8(0);
  899. if seen_trns {
  900. key = u8(mem.slice_data_cast([]u16be, trns.data)[0]);
  901. }
  902. for len(p) > 0 {
  903. r := p[0];
  904. alpha := u8(1);
  905. if seen_trns {
  906. if r == key {
  907. if seen_bkgd {
  908. bc := img.background.([3]u16);
  909. r = u8(bc[0]);
  910. } else {
  911. alpha = 0; // Keyed transparency
  912. }
  913. }
  914. if premultiply {
  915. r *= alpha;
  916. }
  917. }
  918. o[0] = r;
  919. o[1] = r;
  920. o[2] = r;
  921. if out_image_channels == 4 {
  922. o[3] = alpha * 255;
  923. }
  924. p = p[1:];
  925. o = o[out_image_channels:];
  926. }
  927. case 2:
  928. // Gray with alpha, we shouldn't have a tRNS chunk.
  929. bg := f32(0.0);
  930. if seen_bkgd {
  931. bg = f32(img.background.([3]u16)[0]);
  932. }
  933. for len(p) > 0 {
  934. r := p[0];
  935. if seen_bkgd {
  936. alpha := f32(p[1]) / f32(255);
  937. c := u8(f32(r) * alpha + (1.0 - alpha) * bg);
  938. o[0] = c;
  939. o[1] = c;
  940. o[2] = c;
  941. /*
  942. After BG blending, the pixel is now fully opaque.
  943. Update the value we'll write to the output alpha.
  944. */
  945. p[1] = 255;
  946. } else if .alpha_premultiply in options {
  947. alpha := p[1];
  948. c := u8(f32(r) * f32(alpha) / f32(255));
  949. o[0] = c;
  950. o[1] = c;
  951. o[2] = c;
  952. } else {
  953. o[0] = r;
  954. o[1] = r;
  955. o[2] = r;
  956. }
  957. if out_image_channels == 4 {
  958. o[3] = p[1];
  959. }
  960. p = p[2:];
  961. o = o[out_image_channels:];
  962. }
  963. case 3:
  964. // Color without Alpha. We may still have a tRNS chunk
  965. key: []u8;
  966. if seen_trns {
  967. /*
  968. For 8-bit images, the tRNS chunk still contains a triple in u16be.
  969. We use only the low byte in this case.
  970. */
  971. key = []u8{trns.data[1], trns.data[3], trns.data[5]};
  972. }
  973. for len(p) > 0 {
  974. r := p[0];
  975. g := p[1];
  976. b := p[2];
  977. alpha := u8(1); // Default to full opaque
  978. if seen_trns {
  979. if r == key[0] && g == key[1] && b == key[2] {
  980. if seen_bkgd {
  981. c := img.background.([3]u16);
  982. r = u8(c[0]);
  983. g = u8(c[1]);
  984. b = u8(c[2]);
  985. } else {
  986. alpha = 0; // Keyed transparency
  987. }
  988. }
  989. if premultiply {
  990. r *= alpha;
  991. g *= alpha;
  992. b *= alpha;
  993. }
  994. }
  995. o[0] = r;
  996. o[1] = g;
  997. o[2] = b;
  998. if out_image_channels == 4 {
  999. o[3] = alpha * 255;
  1000. }
  1001. p = p[3:];
  1002. o = o[out_image_channels:];
  1003. }
  1004. case 4:
  1005. // Color with Alpha, can't have tRNS.
  1006. for len(p) > 0 {
  1007. r := p[0];
  1008. g := p[1];
  1009. b := p[2];
  1010. a := p[3];
  1011. if seen_bkgd {
  1012. alpha := f32(a) / 255.0;
  1013. c := img.background.([3]u16);
  1014. rb := f32(c[0]) * (1.0 - alpha);
  1015. gb := f32(c[1]) * (1.0 - alpha);
  1016. bb := f32(c[2]) * (1.0 - alpha);
  1017. o[0] = u8(f32(r) * alpha + rb);
  1018. o[1] = u8(f32(g) * alpha + gb);
  1019. o[2] = u8(f32(b) * alpha + bb);
  1020. /*
  1021. After BG blending, the pixel is now fully opaque.
  1022. Update the value we'll write to the output alpha.
  1023. */
  1024. a = 255;
  1025. } else if premultiply {
  1026. alpha := f32(a) / 255.0;
  1027. o[0] = u8(f32(r) * alpha);
  1028. o[1] = u8(f32(g) * alpha);
  1029. o[2] = u8(f32(b) * alpha);
  1030. } else {
  1031. o[0] = r;
  1032. o[1] = g;
  1033. o[2] = b;
  1034. }
  1035. if out_image_channels == 4 {
  1036. o[3] = a;
  1037. }
  1038. p = p[4:];
  1039. o = o[out_image_channels:];
  1040. }
  1041. case:
  1042. unreachable("We should never seen # channels other than 1-4 inclusive.");
  1043. }
  1044. img.pixels = t;
  1045. img.channels = out_image_channels;
  1046. } else {
  1047. /*
  1048. This may change if we ever don't expand 1, 2 and 4 bit images. But, those raw
  1049. returns will likely bypass this processing pipeline.
  1050. */
  1051. unreachable("We should never see bit depths other than 8, 16 and 'Paletted' here.");
  1052. }
  1053. return img, nil;
  1054. }
  1055. filter_paeth :: #force_inline proc(left, up, up_left: u8) -> u8 {
  1056. aa, bb, cc := i16(left), i16(up), i16(up_left);
  1057. p := aa + bb - cc;
  1058. pa := abs(p - aa);
  1059. pb := abs(p - bb);
  1060. pc := abs(p - cc);
  1061. if pa <= pb && pa <= pc {
  1062. return left;
  1063. }
  1064. if pb <= pc {
  1065. return up;
  1066. }
  1067. return up_left;
  1068. }
  1069. Filter_Params :: struct #packed {
  1070. src: []u8,
  1071. dest: []u8,
  1072. width: int,
  1073. height: int,
  1074. depth: int,
  1075. channels: int,
  1076. rescale: bool,
  1077. }
  1078. depth_scale_table :: []u8{0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01};
  1079. // @(optimization_mode="speed")
  1080. defilter_8 :: proc(params: ^Filter_Params) -> (ok: bool) {
  1081. using params;
  1082. row_stride := channels * width;
  1083. // TODO: See about doing a Duff's #unroll where practicable
  1084. // Apron so we don't need to special case first rows.
  1085. up := make([]u8, row_stride, context.temp_allocator);
  1086. ok = true;
  1087. for _ in 0..<height {
  1088. nk := row_stride - channels;
  1089. filter := Row_Filter(src[0]); src = src[1:];
  1090. switch filter {
  1091. case .None:
  1092. copy(dest, src[:row_stride]);
  1093. case .Sub:
  1094. for i := 0; i < channels; i += 1 {
  1095. dest[i] = src[i];
  1096. }
  1097. for k := 0; k < nk; k += 1 {
  1098. dest[channels+k] = (src[channels+k] + dest[k]) & 255;
  1099. }
  1100. case .Up:
  1101. for k := 0; k < row_stride; k += 1 {
  1102. dest[k] = (src[k] + up[k]) & 255;
  1103. }
  1104. case .Average:
  1105. for i := 0; i < channels; i += 1 {
  1106. avg := up[i] >> 1;
  1107. dest[i] = (src[i] + avg) & 255;
  1108. }
  1109. for k := 0; k < nk; k += 1 {
  1110. avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
  1111. dest[channels+k] = (src[channels+k] + avg) & 255;
  1112. }
  1113. case .Paeth:
  1114. for i := 0; i < channels; i += 1 {
  1115. paeth := filter_paeth(0, up[i], 0);
  1116. dest[i] = (src[i] + paeth) & 255;
  1117. }
  1118. for k := 0; k < nk; k += 1 {
  1119. paeth := filter_paeth(dest[k], up[channels+k], up[k]);
  1120. dest[channels+k] = (src[channels+k] + paeth) & 255;
  1121. }
  1122. case:
  1123. return false;
  1124. }
  1125. src = src[row_stride:];
  1126. up = dest;
  1127. dest = dest[row_stride:];
  1128. }
  1129. return;
  1130. }
  1131. // @(optimization_mode="speed")
  1132. defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_check {
  1133. using params;
  1134. ok = true;
  1135. row_stride_in := ((channels * width * depth) + 7) >> 3;
  1136. row_stride_out := channels * width;
  1137. // Store defiltered bytes rightmost so we can widen in-place.
  1138. row_offset := row_stride_out - row_stride_in;
  1139. // Save original dest because we'll need it for the bit widening.
  1140. orig_dest := dest;
  1141. // TODO: See about doing a Duff's #unroll where practicable
  1142. // Apron so we don't need to special case first rows.
  1143. up := make([]u8, row_stride_out, context.temp_allocator);
  1144. #no_bounds_check for _ in 0..<height {
  1145. nk := row_stride_in - channels;
  1146. dest = dest[row_offset:];
  1147. filter := Row_Filter(src[0]); src = src[1:];
  1148. switch filter {
  1149. case .None:
  1150. copy(dest, src[:row_stride_in]);
  1151. case .Sub:
  1152. for i in 0..=channels {
  1153. dest[i] = src[i];
  1154. }
  1155. for k in 0..=nk {
  1156. dest[channels+k] = (src[channels+k] + dest[k]) & 255;
  1157. }
  1158. case .Up:
  1159. for k in 0..=row_stride_in {
  1160. dest[k] = (src[k] + up[k]) & 255;
  1161. }
  1162. case .Average:
  1163. for i in 0..=channels {
  1164. avg := up[i] >> 1;
  1165. dest[i] = (src[i] + avg) & 255;
  1166. }
  1167. for k in 0..=nk {
  1168. avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
  1169. dest[channels+k] = (src[channels+k] + avg) & 255;
  1170. }
  1171. case .Paeth:
  1172. for i in 0..=channels {
  1173. paeth := filter_paeth(0, up[i], 0);
  1174. dest[i] = (src[i] + paeth) & 255;
  1175. }
  1176. for k in 0..=nk {
  1177. paeth := filter_paeth(dest[k], up[channels+k], up[k]);
  1178. dest[channels+k] = (src[channels+k] + paeth) & 255;
  1179. }
  1180. case:
  1181. return false;
  1182. }
  1183. src = src[row_stride_in:];
  1184. up = dest;
  1185. dest = dest[row_stride_in:];
  1186. }
  1187. // Let's expand the bits
  1188. dest = orig_dest;
  1189. // Don't rescale the bits if we're a paletted image.
  1190. dsc := depth_scale_table;
  1191. scale := rescale ? dsc[depth] : 1;
  1192. /*
  1193. For sBIT support we should probably set scale to 1 and mask the significant bits.
  1194. Seperately, do we want to support packed pixels? i.e defiltering only, no expansion?
  1195. If so, all we have to do is call defilter_8 for that case and not set img.depth to 8.
  1196. */
  1197. for j := 0; j < height; j += 1 {
  1198. src = dest[row_offset:];
  1199. switch depth {
  1200. case 4:
  1201. k := row_stride_out;
  1202. for ; k >= 2; k -= 2 {
  1203. c := src[0];
  1204. dest[0] = scale * (c >> 4);
  1205. dest[1] = scale * (c & 15);
  1206. dest = dest[2:]; src = src[1:];
  1207. }
  1208. if k > 0 {
  1209. c := src[0];
  1210. dest[0] = scale * (c >> 4);
  1211. dest = dest[1:];
  1212. }
  1213. case 2:
  1214. k := row_stride_out;
  1215. for ; k >= 4; k -= 4 {
  1216. c := src[0];
  1217. dest[0] = scale * ((c >> 6) );
  1218. dest[1] = scale * ((c >> 4) & 3);
  1219. dest[2] = scale * ((c >> 2) & 3);
  1220. dest[3] = scale * ((c ) & 3);
  1221. dest = dest[4:]; src = src[1:];
  1222. }
  1223. if k > 0 {
  1224. c := src[0];
  1225. dest[0] = scale * ((c >> 6) );
  1226. if k > 1 {
  1227. dest[1] = scale * ((c >> 4) & 3);
  1228. }
  1229. if k > 2 {
  1230. dest[2] = scale * ((c >> 2) & 3);
  1231. }
  1232. dest = dest[k:];
  1233. }
  1234. case 1:
  1235. k := row_stride_out;
  1236. for ; k >= 8; k -= 8 {
  1237. c := src[0];
  1238. dest[0] = scale * ((c >> 7) );
  1239. dest[1] = scale * ((c >> 6) & 1);
  1240. dest[2] = scale * ((c >> 5) & 1);
  1241. dest[3] = scale * ((c >> 4) & 1);
  1242. dest[4] = scale * ((c >> 3) & 1);
  1243. dest[5] = scale * ((c >> 2) & 1);
  1244. dest[6] = scale * ((c >> 1) & 1);
  1245. dest[7] = scale * ((c ) & 1);
  1246. dest = dest[8:]; src = src[1:];
  1247. }
  1248. if k > 0 {
  1249. c := src[0];
  1250. dest[0] = scale * ((c >> 7) );
  1251. if k > 1 {
  1252. dest[1] = scale * ((c >> 6) & 1);
  1253. }
  1254. if k > 2 {
  1255. dest[2] = scale * ((c >> 5) & 1);
  1256. }
  1257. if k > 3 {
  1258. dest[3] = scale * ((c >> 4) & 1);
  1259. }
  1260. if k > 4 {
  1261. dest[4] = scale * ((c >> 3) & 1);
  1262. }
  1263. if k > 5 {
  1264. dest[5] = scale * ((c >> 2) & 1);
  1265. }
  1266. if k > 6 {
  1267. dest[6] = scale * ((c >> 1) & 1);
  1268. }
  1269. dest = dest[k:];
  1270. }
  1271. }
  1272. }
  1273. return;
  1274. }
  1275. // @(optimization_mode="speed")
  1276. defilter_16 :: proc(params: ^Filter_Params) -> (ok: bool) {
  1277. using params;
  1278. ok = true;
  1279. stride := channels * 2;
  1280. row_stride := width * stride;
  1281. // TODO: See about doing a Duff's #unroll where practicable
  1282. // Apron so we don't need to special case first rows.
  1283. up := make([]u8, row_stride, context.temp_allocator);
  1284. for y := 0; y < height; y += 1 {
  1285. nk := row_stride - stride;
  1286. filter := Row_Filter(src[0]); src = src[1:];
  1287. switch filter {
  1288. case .None:
  1289. copy(dest, src[:row_stride]);
  1290. case .Sub:
  1291. for i := 0; i < stride; i += 1 {
  1292. dest[i] = src[i];
  1293. }
  1294. for k := 0; k < nk; k += 1 {
  1295. dest[stride+k] = (src[stride+k] + dest[k]) & 255;
  1296. }
  1297. case .Up:
  1298. for k := 0; k < row_stride; k += 1 {
  1299. dest[k] = (src[k] + up[k]) & 255;
  1300. }
  1301. case .Average:
  1302. for i := 0; i < stride; i += 1 {
  1303. avg := up[i] >> 1;
  1304. dest[i] = (src[i] + avg) & 255;
  1305. }
  1306. for k := 0; k < nk; k += 1 {
  1307. avg := u8((u16(up[stride+k]) + u16(dest[k])) >> 1);
  1308. dest[stride+k] = (src[stride+k] + avg) & 255;
  1309. }
  1310. case .Paeth:
  1311. for i := 0; i < stride; i += 1 {
  1312. paeth := filter_paeth(0, up[i], 0);
  1313. dest[i] = (src[i] + paeth) & 255;
  1314. }
  1315. for k := 0; k < nk; k += 1 {
  1316. paeth := filter_paeth(dest[k], up[stride+k], up[k]);
  1317. dest[stride+k] = (src[stride+k] + paeth) & 255;
  1318. }
  1319. case:
  1320. return false;
  1321. }
  1322. src = src[row_stride:];
  1323. up = dest;
  1324. dest = dest[row_stride:];
  1325. }
  1326. return;
  1327. }
  1328. defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^IHDR, options: Options) -> (err: compress.Error) {
  1329. input := bytes.buffer_to_bytes(filter_bytes);
  1330. width := int(header.width);
  1331. height := int(header.height);
  1332. channels := int(img.channels);
  1333. depth := int(header.bit_depth);
  1334. rescale := .Color not_in header.color_type;
  1335. bytes_per_channel := depth == 16 ? 2 : 1;
  1336. num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8);
  1337. resize(&img.pixels.buf, num_bytes);
  1338. filter_ok: bool;
  1339. if header.interlace_method != .Adam7 {
  1340. params := Filter_Params{
  1341. src = input,
  1342. width = width,
  1343. height = height,
  1344. channels = channels,
  1345. depth = depth,
  1346. rescale = rescale,
  1347. dest = img.pixels.buf[:],
  1348. };
  1349. if depth == 8 {
  1350. filter_ok = defilter_8(&params);
  1351. } else if depth < 8 {
  1352. filter_ok = defilter_less_than_8(&params);
  1353. img.depth = 8;
  1354. } else {
  1355. filter_ok = defilter_16(&params);
  1356. }
  1357. if !filter_ok {
  1358. // Caller will destroy buffer for us.
  1359. return E_PNG.Unknown_Filter_Method;
  1360. }
  1361. } else {
  1362. /*
  1363. For deinterlacing we need to make a temporary buffer, defiilter part of the image,
  1364. and copy that back into the actual output buffer.
  1365. */
  1366. for p := 0; p < 7; p += 1 {
  1367. i,j,x,y: int;
  1368. x = (width - ADAM7_X_ORIG[p] + ADAM7_X_SPACING[p] - 1) / ADAM7_X_SPACING[p];
  1369. y = (height - ADAM7_Y_ORIG[p] + ADAM7_Y_SPACING[p] - 1) / ADAM7_Y_SPACING[p];
  1370. if x > 0 && y > 0 {
  1371. temp: bytes.Buffer;
  1372. temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8);
  1373. resize(&temp.buf, temp_len);
  1374. params := Filter_Params{
  1375. src = input,
  1376. width = x,
  1377. height = y,
  1378. channels = channels,
  1379. depth = depth,
  1380. rescale = rescale,
  1381. dest = temp.buf[:],
  1382. };
  1383. if depth == 8 {
  1384. filter_ok = defilter_8(&params);
  1385. } else if depth < 8 {
  1386. filter_ok = defilter_less_than_8(&params);
  1387. img.depth = 8;
  1388. } else {
  1389. filter_ok = defilter_16(&params);
  1390. }
  1391. if !filter_ok {
  1392. // Caller will destroy buffer for us.
  1393. return E_PNG.Unknown_Filter_Method;
  1394. }
  1395. t := temp.buf[:];
  1396. for j = 0; j < y; j += 1 {
  1397. for i = 0; i < x; i += 1 {
  1398. out_y := j * ADAM7_Y_SPACING[p] + ADAM7_Y_ORIG[p];
  1399. out_x := i * ADAM7_X_SPACING[p] + ADAM7_X_ORIG[p];
  1400. out_off := out_y * width * channels * bytes_per_channel;
  1401. out_off += out_x * channels * bytes_per_channel;
  1402. for z := 0; z < channels * bytes_per_channel; z += 1 {
  1403. img.pixels.buf[out_off + z] = t[z];
  1404. }
  1405. t = t[channels * bytes_per_channel:];
  1406. }
  1407. }
  1408. bytes.buffer_destroy(&temp);
  1409. input_stride := compute_buffer_size(x, y, channels, depth, 1);
  1410. input = input[input_stride:];
  1411. }
  1412. }
  1413. }
  1414. when ODIN_ENDIAN == "little" {
  1415. if img.depth == 16 {
  1416. // The pixel components are in Big Endian. Let's byteswap.
  1417. input := mem.slice_data_cast([]u16be, img.pixels.buf[:]);
  1418. output := mem.slice_data_cast([]u16 , img.pixels.buf[:]);
  1419. #no_bounds_check for v, i in input {
  1420. output[i] = u16(v);
  1421. }
  1422. }
  1423. }
  1424. return nil;
  1425. }
  1426. load :: proc{load_from_file, load_from_slice, load_from_stream};