; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc INCLUDELIB OLDNAMES PUBLIC ??_C@_0BD@CBEDEJPH@unknown?5image?5type@ ; `string' PUBLIC ??_C@_08NOGIMCHF@outofmem@ ; `string' PUBLIC ??_C@_02JDPG@rb@ ; `string' PUBLIC ??_C@_0M@JPDHFAGK@can?8t?5fopen@ ; `string' PUBLIC ??_C@_0CB@DDANHPKI@can?8t?5fopen?0?5Unable?5to?5open?5fil@ ; `string' PUBLIC ??_C@_0M@MHDBFHD@unsupported@ ; `string' PUBLIC ??_C@_0O@DEFOLMLB@bad?5size?5list@ ; `string' PUBLIC ??_C@_0BB@FOKGPEKG@bad?5code?5lengths@ ; `string' PUBLIC ??_C@_0BB@IIMLINA@bad?5huffman?5code@ ; `string' PUBLIC ??_C@_09IFDKCGFO@bad?5delta@ ; `string' PUBLIC ??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ ; `string' PUBLIC ??_C@_0BA@KLNDOKJD@expected?5marker@ ; `string' PUBLIC ??_C@_0M@LPHNODCG@bad?5DRI?5len@ ; `string' PUBLIC ??_C@_0N@BOFJCHAP@bad?5DQT?5type@ ; `string' PUBLIC ??_C@_0O@CNHKKDIM@bad?5DQT?5table@ ; `string' PUBLIC ??_C@_0P@JLGKOCGN@bad?5DHT?5header@ ; `string' PUBLIC ??_C@_0M@CICAFFCH@bad?5COM?5len@ ; `string' PUBLIC ??_C@_0M@EENLKPDI@bad?5APP?5len@ ; `string' PUBLIC ??_C@_0P@NNGPHMMK@unknown?5marker@ ; `string' PUBLIC ??_C@_0BI@DHFJCMBA@bad?5SOS?5component?5count@ ; `string' PUBLIC ??_C@_0M@GNEHAHOH@bad?5SOS?5len@ ; `string' PUBLIC ??_C@_0M@NOCCBFAC@bad?5DC?5huff@ ; `string' PUBLIC ??_C@_0M@JGMCBLGG@bad?5AC?5huff@ ; `string' PUBLIC ??_C@_07EEJOMGGP@bad?5SOS@ ; `string' PUBLIC ??_C@_0M@DOFMJEMP@bad?5SOF?5len@ ; `string' PUBLIC ??_C@_0L@BCINMEBJ@only?58?9bit@ ; `string' PUBLIC ??_C@_0BB@LNEGOMA@no?5header?5height@ ; `string' PUBLIC ??_C@_07BIDACDEF@0?5width@ ; `string' PUBLIC ??_C@_09OJDLMMBJ@too?5large@ ; `string' PUBLIC ??_C@_0BE@DAPHADHL@bad?5component?5count@ ; `string' PUBLIC ??_C@_05BLPKENEJ@bad?5H@ ; `string' PUBLIC ??_C@_05MPLLHCJG@bad?5V@ ; `string' PUBLIC ??_C@_06LJIHDFHI@bad?5TQ@ ; `string' PUBLIC ??_C@_06CLMBLEP@no?5SOI@ ; `string' PUBLIC ??_C@_06IFCEAHIA@no?5SOF@ ; `string' PUBLIC ??_C@_0M@EPMOIECP@bad?5DNL?5len@ ; `string' PUBLIC ??_C@_0P@PNCLKCLJ@bad?5DNL?5height@ ; `string' PUBLIC ??_C@_0N@KBPNPPBJ@bad?5req_comp@ ; `string' PUBLIC ??_C@_09EOHLEIKL@bad?5sizes@ ; `string' PUBLIC ??_C@_0BA@MDNKOBMC@bad?5codelengths@ ; `string' PUBLIC ??_C@_0BE@IBFIPFO@output?5buffer?5limit@ ; `string' PUBLIC ??_C@_08DIAPIMGJ@bad?5dist@ ; `string' PUBLIC ??_C@_0N@IECDHMDI@zlib?5corrupt@ ; `string' PUBLIC ??_C@_0BB@PIPBCKIA@read?5past?5buffer@ ; `string' PUBLIC ??_C@_0BA@OBKOPAFL@bad?5zlib?5header@ ; `string' PUBLIC ??_C@_0P@DOGMHEBI@no?5preset?5dict@ ; `string' PUBLIC ??_C@_0BA@MCNBDLPD@bad?5compression@ ; `string' PUBLIC ??_C@_0M@DMDNBACF@bad?5png?5sig@ ; `string' PUBLIC ??_C@_0BC@BHMPBBMG@not?5enough?5pixels@ ; `string' PUBLIC ??_C@_0P@FBBCPGMN@invalid?5filter@ ; `string' PUBLIC ??_C@_0O@MKGNGALN@invalid?5width@ ; `string' PUBLIC ??_C@_0O@KBHBNJOK@multiple?5IHDR@ ; `string' PUBLIC ??_C@_0N@POJLKMKK@bad?5IHDR?5len@ ; `string' PUBLIC ??_C@_0BE@EJHIPKNO@1?12?14?18?116?9bit?5only@ ; `string' PUBLIC ??_C@_09MBBNGCKB@bad?5ctype@ ; `string' PUBLIC ??_C@_0BA@MDMBDDFG@bad?5comp?5method@ ; `string' PUBLIC ??_C@_0BC@GHLIKKMD@bad?5filter?5method@ ; `string' PUBLIC ??_C@_0BF@JCGDPBAA@bad?5interlace?5method@ ; `string' PUBLIC ??_C@_0O@FNFBHCOO@0?9pixel?5image@ ; `string' PUBLIC ??_C@_0P@JEAFOMAF@first?5not?5IHDR@ ; `string' PUBLIC ??_C@_0N@JCPAJAKB@invalid?5PLTE@ ; `string' PUBLIC ??_C@_0BA@PCPJHDKJ@tRNS?5after?5IDAT@ ; `string' PUBLIC ??_C@_0BB@CEDNNLBG@tRNS?5before?5PLTE@ ; `string' PUBLIC ??_C@_0N@KDLCCKCH@bad?5tRNS?5len@ ; `string' PUBLIC ??_C@_0BA@ENDPGCHB@tRNS?5with?5alpha@ ; `string' PUBLIC ??_C@_07CKIELOEH@no?5PLTE@ ; `string' PUBLIC ??_C@_0BA@PLHGLONG@IDAT?5size?5limit@ ; `string' PUBLIC ??_C@_09MNNCNKEO@outofdata@ ; `string' PUBLIC ??_C@_07MLPECBNA@no?5IDAT@ ; `string' PUBLIC ??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ ; `string' PUBLIC ??_C@_07IANEBNLB@not?5BMP@ ; `string' PUBLIC ??_C@_07IEJCHBDI@bad?5BMP@ ; `string' PUBLIC ??_C@_0M@KHBIBJBG@unknown?5BMP@ ; `string' PUBLIC ??_C@_07IMHMNOIB@BMP?5RLE@ ; `string' PUBLIC ??_C@_0N@ODCBCBFN@BMP?5JPEG?1PNG@ ; `string' PUBLIC ??_C@_0L@PJHPAMCH@bad?5header@ ; `string' PUBLIC ??_C@_0L@JDPIFELH@bad?5offset@ ; `string' PUBLIC ??_C@_07MALOAKCI@invalid@ ; `string' PUBLIC ??_C@_07JNJHIMGH@bad?5bpp@ ; `string' PUBLIC ??_C@_09DAEBACAB@bad?5masks@ ; `string' PUBLIC ??_C@_0L@DMAPJJO@bad?5format@ ; `string' PUBLIC ??_C@_0M@ILLOCNCO@bad?5palette@ ; `string' PUBLIC ??_C@_07ECNCNLIK@not?5PSD@ ; `string' PUBLIC ??_C@_0O@CHBCDKKC@wrong?5version@ ; `string' PUBLIC ??_C@_0BE@PJBNGDBE@wrong?5channel?5count@ ; `string' PUBLIC ??_C@_0BG@NOLDLPP@unsupported?5bit?5depth@ ; `string' PUBLIC ??_C@_0BD@IOGGBMNK@wrong?5color?5format@ ; `string' PUBLIC ??_C@_07DPPMCAKL@corrupt@ ; `string' PUBLIC ??_C@_04KBFEPHFH@S?$IA?v4@ ; `string' PUBLIC ??_C@_04ELNJHLFH@PICT@ ; `string' PUBLIC ??_C@_08GGMBIFE@bad?5file@ ; `string' PUBLIC ??_C@_07KMJLPAII@not?5GIF@ ; `string' PUBLIC ??_C@_00CNPNBAHC@@ ; `string' PUBLIC ??_C@_0O@MGDACKOJ@no?5clear?5code@ ; `string' PUBLIC ??_C@_0P@GJNJCPDJ@too?5many?5codes@ ; `string' PUBLIC ??_C@_0BH@LOKBIIOJ@illegal?5code?5in?5raster@ ; `string' PUBLIC ??_C@_0BF@GIAALCNJ@bad?5Image?5Descriptor@ ; `string' PUBLIC ??_C@_0BE@NAMJKDNF@missing?5color?5table@ ; `string' PUBLIC ??_C@_0N@DJABBOOH@unknown?5code@ ; `string' PUBLIC ??_C@_0M@HOIDFNFN@?$CD?$DPRADIANCE?6@ ; `string' PUBLIC ??_C@_07KFDJIKCK@?$CD?$DPRGBE?6@ ; `string' PUBLIC ??_C@_0L@NCPEAJBD@?$CD?$DPRADIANCE@ ; `string' PUBLIC ??_C@_06NDOKKIDJ@?$CD?$DPRGBE@ ; `string' PUBLIC ??_C@_07NCIOKENI@not?5HDR@ ; `string' PUBLIC ??_C@_0BH@JFGBLLKC@FORMAT?$DN32?9bit_rle_rgbe@ ; `string' PUBLIC ??_C@_0BD@NKJFFLKL@unsupported?5format@ ; `string' PUBLIC ??_C@_03HKAKGGJN@?9Y?5@ ; `string' PUBLIC ??_C@_0BI@DCNDPIOH@unsupported?5data?5layout@ ; `string' PUBLIC ??_C@_03FOKDFDHG@?$CLX?5@ ; `string' PUBLIC ??_C@_0CA@JBEOCDFN@invalid?5decoded?5scanline?5length@ ; `string' PUBLIC ??_C@_07IDKIDMGJ@bad?5PNM@ ; `string' PUBLIC ??_C@_0BH@OBINMOBC@integer?5parse?5overflow@ ; `string' PUBLIC ??_C@_0BC@CNFMOKHC@max?5value?5?$DO?565535@ ; `string' EXTRN __imp_malloc:PROC EXTRN __imp_fread:PROC EXTRN __imp_feof:PROC EXTRN __imp_ungetc:PROC EXTRN __imp_free:PROC EXTRN __imp_ldexp:PROC EXTRN __imp_strtol:PROC EXTRN __imp_fopen_s:PROC EXTRN __imp_strncmp:PROC EXTRN __imp_fgetc:PROC EXTRN __imp_fseek:PROC EXTRN __imp_realloc:PROC EXTRN __imp_fclose:PROC EXTRN __imp_ferror:PROC EXTRN __imp_ftell:PROC stbi__unpremultiply_on_load_global DD 01H DUP (?) stbi__vertically_flip_on_load_global DD 01H DUP (?) stbi__de_iphone_flag_global DD 01H DUP (?) _BSS ENDS stbi__jbias DD 00H DD 0ffffffffH DD 0fffffffdH DD 0fffffff9H DD 0fffffff1H DD 0ffffffe1H DD 0ffffffc1H DD 0ffffff81H DD 0ffffff01H DD 0fffffe01H DD 0fffffc01H DD 0fffff801H DD 0fffff001H DD 0ffffe001H DD 0ffffc001H DD 0ffff8001H stbi__zdefault_length DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 09H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 07H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H DB 08H stbi__jpeg_dezigzag DB 00H DB 01H DB 08H DB 010H DB 09H DB 02H DB 03H DB 0aH DB 011H DB 018H DB 020H DB 019H DB 012H DB 0bH DB 04H DB 05H DB 0cH DB 013H DB 01aH DB 021H DB 028H DB 030H DB 029H DB 022H DB 01bH DB 014H DB 0dH DB 06H DB 07H DB 0eH DB 015H DB 01cH DB 023H DB 02aH DB 031H DB 038H DB 039H DB 032H DB 02bH DB 024H DB 01dH DB 016H DB 0fH DB 017H DB 01eH DB 025H DB 02cH DB 033H DB 03aH DB 03bH DB 034H DB 02dH DB 026H DB 01fH DB 027H DB 02eH DB 035H DB 03cH DB 03dH DB 036H DB 02fH DB 037H DB 03eH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH DB 03fH ORG $+1 ?rgb@?5??stbi__process_frame_header@@9@9 DB 052H ; `stbi__process_frame_header'::`6'::rgb DB 047H DB 042H ORG $+13 stbi__zlength_base DD 03H DD 04H DD 05H DD 06H DD 07H DD 08H DD 09H DD 0aH DD 0bH DD 0dH DD 0fH DD 011H DD 013H DD 017H DD 01bH DD 01fH DD 023H DD 02bH DD 033H DD 03bH DD 043H DD 053H DD 063H DD 073H DD 083H DD 0a3H DD 0c3H DD 0e3H DD 0102H DD 00H DD 00H ORG $+4 stbi__zdist_base DD 01H DD 02H DD 03H DD 04H DD 05H DD 07H DD 09H DD 0dH DD 011H DD 019H DD 021H DD 031H DD 041H DD 061H DD 081H DD 0c1H DD 0101H DD 0181H DD 0201H DD 0301H DD 0401H DD 0601H DD 0801H DD 0c01H DD 01001H DD 01801H DD 02001H DD 03001H DD 04001H DD 06001H DD 00H DD 00H stbi__bmask DD 00H DD 01H DD 03H DD 07H DD 0fH DD 01fH DD 03fH DD 07fH DD 0ffH DD 01ffH DD 03ffH DD 07ffH DD 0fffH DD 01fffH DD 03fffH DD 07fffH DD 0ffffH ORG $+12 stbi__zlength_extra DD 00H DD 00H DD 00H DD 00H DD 00H DD 00H DD 00H DD 00H DD 01H DD 01H DD 01H DD 01H DD 02H DD 02H DD 02H DD 02H DD 03H DD 03H DD 03H DD 03H DD 04H DD 04H DD 04H DD 04H DD 05H DD 05H DD 05H DD 05H DD 00H DD 00H DD 00H ?tag@?O@??stbi__process_marker@@9@9 DB 04aH ; `stbi__process_marker'::`14'::tag DB 046H DB 049H DB 046H DB 00H ORG $+3 first_row_filter DB 00H DB 01H DB 00H DB 05H DB 06H ORG $+7 ?length_dezigzag@?1??stbi__compute_huffman_codes@@9@9 DB 010H ; `stbi__compute_huffman_codes'::`2'::length_dezigzag DB 011H DB 012H DB 00H DB 08H DB 07H DB 09H DB 06H DB 0aH DB 05H DB 0bH DB 04H DB 0cH DB 03H DB 0dH DB 02H DB 0eH DB 01H DB 0fH ORG $+5 stbi__depth_scale_table DB 00H DB 0ffH DB 055H DB 00H DB 011H DB 00H DB 00H DB 00H DB 01H ORG $+7 stbi__zdefault_distance DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H DB 05H ?tag@?BA@??stbi__process_marker@@9@9 DB 041H ; `stbi__process_marker'::`16'::tag DB 064H DB 06fH DB 062H DB 065H DB 00H ORG $+2 ?shift_table@?1??stbi__shiftsigned@@9@9 DD 00H ; `stbi__shiftsigned'::`2'::shift_table DD 00H DD 00H DD 01H DD 00H DD 02H DD 04H DD 06H DD 00H ORG $+4 ?mul_table@?1??stbi__shiftsigned@@9@9 DD 00H ; `stbi__shiftsigned'::`2'::mul_table DD 0ffH DD 055H DD 049H DD 011H DD 021H DD 041H DD 081H DD 01H stbi__h2l_gamma_i DD 03ee8ba2er ; 0.454545 stbi__zdist_extra DD 00H DD 00H DD 00H DD 00H DD 01H DD 01H DD 02H DD 02H DD 03H DD 03H DD 04H DD 04H DD 05H DD 05H DD 06H DD 06H DD 07H DD 07H DD 08H DD 08H DD 09H DD 09H DD 0aH DD 0aH DD 0bH DD 0bH DD 0cH DD 0cH DD 0dH DD 0dH ORG $+8 stbi__h2l_scale_i DD 03f800000r ; 1 ORG $+4 ?png_sig@?1??stbi__check_png_header@@9@9 DB 089H ; `stbi__check_png_header'::`2'::png_sig DB 050H DB 04eH DB 047H DB 0dH DB 0aH DB 01aH DB 0aH CONST ENDS ; COMDAT ??_C@_0BC@CNFMOKHC@max?5value?5?$DO?565535@ CONST SEGMENT ??_C@_0BC@CNFMOKHC@max?5value?5?$DO?565535@ DB 'max value > 65535', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BH@OBINMOBC@integer?5parse?5overflow@ CONST SEGMENT ??_C@_0BH@OBINMOBC@integer?5parse?5overflow@ DB 'integer parse overflow', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07IDKIDMGJ@bad?5PNM@ CONST SEGMENT ??_C@_07IDKIDMGJ@bad?5PNM@ DB 'bad PNM', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0CA@JBEOCDFN@invalid?5decoded?5scanline?5length@ CONST SEGMENT ??_C@_0CA@JBEOCDFN@invalid?5decoded?5scanline?5length@ DB 'invalid decode' DB 'd scanline length', 00H ; `string' CONST ENDS ; COMDAT ??_C@_03FOKDFDHG@?$CLX?5@ CONST SEGMENT ??_C@_03FOKDFDHG@?$CLX?5@ DB '+X ', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BI@DCNDPIOH@unsupported?5data?5layout@ CONST SEGMENT ??_C@_0BI@DCNDPIOH@unsupported?5data?5layout@ DB 'unsupported data layout' DB 00H ; `string' CONST ENDS ; COMDAT ??_C@_03HKAKGGJN@?9Y?5@ CONST SEGMENT ??_C@_03HKAKGGJN@?9Y?5@ DB '-Y ', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BD@NKJFFLKL@unsupported?5format@ CONST SEGMENT ??_C@_0BD@NKJFFLKL@unsupported?5format@ DB 'unsupported format', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BH@JFGBLLKC@FORMAT?$DN32?9bit_rle_rgbe@ CONST SEGMENT ??_C@_0BH@JFGBLLKC@FORMAT?$DN32?9bit_rle_rgbe@ DB 'FORMAT=32-bit_rle_rgbe' DB 00H ; `string' CONST ENDS ; COMDAT ??_C@_07NCIOKENI@not?5HDR@ CONST SEGMENT ??_C@_07NCIOKENI@not?5HDR@ DB 'not HDR', 00H ; `string' CONST ENDS ; COMDAT ??_C@_06NDOKKIDJ@?$CD?$DPRGBE@ CONST SEGMENT ??_C@_06NDOKKIDJ@?$CD?$DPRGBE@ DB '#?RGBE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0L@NCPEAJBD@?$CD?$DPRADIANCE@ CONST SEGMENT ??_C@_0L@NCPEAJBD@?$CD?$DPRADIANCE@ DB '#?RADIANCE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07KFDJIKCK@?$CD?$DPRGBE?6@ CONST SEGMENT ??_C@_07KFDJIKCK@?$CD?$DPRGBE?6@ DB '#?RGBE', 0aH, 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@HOIDFNFN@?$CD?$DPRADIANCE?6@ CONST SEGMENT ??_C@_0M@HOIDFNFN@?$CD?$DPRADIANCE?6@ DB '#?RADIANCE', 0aH, 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@DJABBOOH@unknown?5code@ CONST SEGMENT ??_C@_0N@DJABBOOH@unknown?5code@ DB 'unknown code', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BE@NAMJKDNF@missing?5color?5table@ CONST SEGMENT ??_C@_0BE@NAMJKDNF@missing?5color?5table@ DB 'missing color table', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BF@GIAALCNJ@bad?5Image?5Descriptor@ CONST SEGMENT ??_C@_0BF@GIAALCNJ@bad?5Image?5Descriptor@ DB 'bad Image Descriptor', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BH@LOKBIIOJ@illegal?5code?5in?5raster@ CONST SEGMENT ??_C@_0BH@LOKBIIOJ@illegal?5code?5in?5raster@ DB 'illegal code in raster', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@GJNJCPDJ@too?5many?5codes@ CONST SEGMENT ??_C@_0P@GJNJCPDJ@too?5many?5codes@ DB 'too many codes', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@MGDACKOJ@no?5clear?5code@ CONST SEGMENT ??_C@_0O@MGDACKOJ@no?5clear?5code@ DB 'no clear code', 00H ; `string' CONST ENDS ; COMDAT ??_C@_00CNPNBAHC@@ CONST SEGMENT ??_C@_00CNPNBAHC@@ DB 00H ; `string' CONST ENDS ; COMDAT ??_C@_07KMJLPAII@not?5GIF@ CONST SEGMENT ??_C@_07KMJLPAII@not?5GIF@ DB 'not GIF', 00H ; `string' CONST ENDS ; COMDAT ??_C@_08GGMBIFE@bad?5file@ CONST SEGMENT ??_C@_08GGMBIFE@bad?5file@ DB 'bad file', 00H ; `string' CONST ENDS ; COMDAT ??_C@_04ELNJHLFH@PICT@ CONST SEGMENT ??_C@_04ELNJHLFH@PICT@ DB 'PICT', 00H ; `string' CONST ENDS ; COMDAT ??_C@_04KBFEPHFH@S?$IA?v4@ CONST SEGMENT ??_C@_04KBFEPHFH@S?$IA?v4@ DB 'S', 080H, 0f6H, '4', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07DPPMCAKL@corrupt@ CONST SEGMENT ??_C@_07DPPMCAKL@corrupt@ DB 'corrupt', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BD@IOGGBMNK@wrong?5color?5format@ CONST SEGMENT ??_C@_0BD@IOGGBMNK@wrong?5color?5format@ DB 'wrong color format', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BG@NOLDLPP@unsupported?5bit?5depth@ CONST SEGMENT ??_C@_0BG@NOLDLPP@unsupported?5bit?5depth@ DB 'unsupported bit depth', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BE@PJBNGDBE@wrong?5channel?5count@ CONST SEGMENT ??_C@_0BE@PJBNGDBE@wrong?5channel?5count@ DB 'wrong channel count', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@CHBCDKKC@wrong?5version@ CONST SEGMENT ??_C@_0O@CHBCDKKC@wrong?5version@ DB 'wrong version', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07ECNCNLIK@not?5PSD@ CONST SEGMENT ??_C@_07ECNCNLIK@not?5PSD@ DB 'not PSD', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@ILLOCNCO@bad?5palette@ CONST SEGMENT ??_C@_0M@ILLOCNCO@bad?5palette@ DB 'bad palette', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0L@DMAPJJO@bad?5format@ CONST SEGMENT ??_C@_0L@DMAPJJO@bad?5format@ DB 'bad format', 00H ; `string' CONST ENDS ; COMDAT ??_C@_09DAEBACAB@bad?5masks@ CONST SEGMENT ??_C@_09DAEBACAB@bad?5masks@ DB 'bad masks', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07JNJHIMGH@bad?5bpp@ CONST SEGMENT ??_C@_07JNJHIMGH@bad?5bpp@ DB 'bad bpp', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07MALOAKCI@invalid@ CONST SEGMENT ??_C@_07MALOAKCI@invalid@ DB 'invalid', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0L@JDPIFELH@bad?5offset@ CONST SEGMENT ??_C@_0L@JDPIFELH@bad?5offset@ DB 'bad offset', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0L@PJHPAMCH@bad?5header@ CONST SEGMENT ??_C@_0L@PJHPAMCH@bad?5header@ DB 'bad header', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@ODCBCBFN@BMP?5JPEG?1PNG@ CONST SEGMENT ??_C@_0N@ODCBCBFN@BMP?5JPEG?1PNG@ DB 'BMP JPEG/PNG', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07IMHMNOIB@BMP?5RLE@ CONST SEGMENT ??_C@_07IMHMNOIB@BMP?5RLE@ DB 'BMP RLE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@KHBIBJBG@unknown?5BMP@ CONST SEGMENT ??_C@_0M@KHBIBJBG@unknown?5BMP@ DB 'unknown BMP', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07IEJCHBDI@bad?5BMP@ CONST SEGMENT ??_C@_07IEJCHBDI@bad?5BMP@ DB 'bad BMP', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07IANEBNLB@not?5BMP@ CONST SEGMENT ??_C@_07IANEBNLB@not?5BMP@ DB 'not BMP', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ CONST SEGMENT ??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ DB 'bad bits_per_channel', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07MLPECBNA@no?5IDAT@ CONST SEGMENT ??_C@_07MLPECBNA@no?5IDAT@ DB 'no IDAT', 00H ; `string' CONST ENDS ; COMDAT ??_C@_09MNNCNKEO@outofdata@ CONST SEGMENT ??_C@_09MNNCNKEO@outofdata@ DB 'outofdata', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@PLHGLONG@IDAT?5size?5limit@ CONST SEGMENT ??_C@_0BA@PLHGLONG@IDAT?5size?5limit@ DB 'IDAT size limit', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07CKIELOEH@no?5PLTE@ CONST SEGMENT ??_C@_07CKIELOEH@no?5PLTE@ DB 'no PLTE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@ENDPGCHB@tRNS?5with?5alpha@ CONST SEGMENT ??_C@_0BA@ENDPGCHB@tRNS?5with?5alpha@ DB 'tRNS with alpha', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@KDLCCKCH@bad?5tRNS?5len@ CONST SEGMENT ??_C@_0N@KDLCCKCH@bad?5tRNS?5len@ DB 'bad tRNS len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BB@CEDNNLBG@tRNS?5before?5PLTE@ CONST SEGMENT ??_C@_0BB@CEDNNLBG@tRNS?5before?5PLTE@ DB 'tRNS before PLTE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@PCPJHDKJ@tRNS?5after?5IDAT@ CONST SEGMENT ??_C@_0BA@PCPJHDKJ@tRNS?5after?5IDAT@ DB 'tRNS after IDAT', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@JCPAJAKB@invalid?5PLTE@ CONST SEGMENT ??_C@_0N@JCPAJAKB@invalid?5PLTE@ DB 'invalid PLTE', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@JEAFOMAF@first?5not?5IHDR@ CONST SEGMENT ??_C@_0P@JEAFOMAF@first?5not?5IHDR@ DB 'first not IHDR', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@FNFBHCOO@0?9pixel?5image@ CONST SEGMENT ??_C@_0O@FNFBHCOO@0?9pixel?5image@ DB '0-pixel image', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BF@JCGDPBAA@bad?5interlace?5method@ CONST SEGMENT ??_C@_0BF@JCGDPBAA@bad?5interlace?5method@ DB 'bad interlace method', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BC@GHLIKKMD@bad?5filter?5method@ CONST SEGMENT ??_C@_0BC@GHLIKKMD@bad?5filter?5method@ DB 'bad filter method', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@MDMBDDFG@bad?5comp?5method@ CONST SEGMENT ??_C@_0BA@MDMBDDFG@bad?5comp?5method@ DB 'bad comp method', 00H ; `string' CONST ENDS ; COMDAT ??_C@_09MBBNGCKB@bad?5ctype@ CONST SEGMENT ??_C@_09MBBNGCKB@bad?5ctype@ DB 'bad ctype', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BE@EJHIPKNO@1?12?14?18?116?9bit?5only@ CONST SEGMENT ??_C@_0BE@EJHIPKNO@1?12?14?18?116?9bit?5only@ DB '1/2/4/8/16-bit only', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@POJLKMKK@bad?5IHDR?5len@ CONST SEGMENT ??_C@_0N@POJLKMKK@bad?5IHDR?5len@ DB 'bad IHDR len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@KBHBNJOK@multiple?5IHDR@ CONST SEGMENT ??_C@_0O@KBHBNJOK@multiple?5IHDR@ DB 'multiple IHDR', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@MKGNGALN@invalid?5width@ CONST SEGMENT ??_C@_0O@MKGNGALN@invalid?5width@ DB 'invalid width', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@FBBCPGMN@invalid?5filter@ CONST SEGMENT ??_C@_0P@FBBCPGMN@invalid?5filter@ DB 'invalid filter', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BC@BHMPBBMG@not?5enough?5pixels@ CONST SEGMENT ??_C@_0BC@BHMPBBMG@not?5enough?5pixels@ DB 'not enough pixels', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@DMDNBACF@bad?5png?5sig@ CONST SEGMENT ??_C@_0M@DMDNBACF@bad?5png?5sig@ DB 'bad png sig', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@MCNBDLPD@bad?5compression@ CONST SEGMENT ??_C@_0BA@MCNBDLPD@bad?5compression@ DB 'bad compression', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@DOGMHEBI@no?5preset?5dict@ CONST SEGMENT ??_C@_0P@DOGMHEBI@no?5preset?5dict@ DB 'no preset dict', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@OBKOPAFL@bad?5zlib?5header@ CONST SEGMENT ??_C@_0BA@OBKOPAFL@bad?5zlib?5header@ DB 'bad zlib header', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BB@PIPBCKIA@read?5past?5buffer@ CONST SEGMENT ??_C@_0BB@PIPBCKIA@read?5past?5buffer@ DB 'read past buffer', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@IECDHMDI@zlib?5corrupt@ CONST SEGMENT ??_C@_0N@IECDHMDI@zlib?5corrupt@ DB 'zlib corrupt', 00H ; `string' CONST ENDS ; COMDAT ??_C@_08DIAPIMGJ@bad?5dist@ CONST SEGMENT ??_C@_08DIAPIMGJ@bad?5dist@ DB 'bad dist', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BE@IBFIPFO@output?5buffer?5limit@ CONST SEGMENT ??_C@_0BE@IBFIPFO@output?5buffer?5limit@ DB 'output buffer limit', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@MDNKOBMC@bad?5codelengths@ CONST SEGMENT ??_C@_0BA@MDNKOBMC@bad?5codelengths@ DB 'bad codelengths', 00H ; `string' CONST ENDS ; COMDAT ??_C@_09EOHLEIKL@bad?5sizes@ CONST SEGMENT ??_C@_09EOHLEIKL@bad?5sizes@ DB 'bad sizes', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@KBPNPPBJ@bad?5req_comp@ CONST SEGMENT ??_C@_0N@KBPNPPBJ@bad?5req_comp@ DB 'bad req_comp', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@PNCLKCLJ@bad?5DNL?5height@ CONST SEGMENT ??_C@_0P@PNCLKCLJ@bad?5DNL?5height@ DB 'bad DNL height', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@EPMOIECP@bad?5DNL?5len@ CONST SEGMENT ??_C@_0M@EPMOIECP@bad?5DNL?5len@ DB 'bad DNL len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_06IFCEAHIA@no?5SOF@ CONST SEGMENT ??_C@_06IFCEAHIA@no?5SOF@ DB 'no SOF', 00H ; `string' CONST ENDS ; COMDAT ??_C@_06CLMBLEP@no?5SOI@ CONST SEGMENT ??_C@_06CLMBLEP@no?5SOI@ DB 'no SOI', 00H ; `string' CONST ENDS ; COMDAT ??_C@_06LJIHDFHI@bad?5TQ@ CONST SEGMENT ??_C@_06LJIHDFHI@bad?5TQ@ DB 'bad TQ', 00H ; `string' CONST ENDS ; COMDAT ??_C@_05MPLLHCJG@bad?5V@ CONST SEGMENT ??_C@_05MPLLHCJG@bad?5V@ DB 'bad V', 00H ; `string' CONST ENDS ; COMDAT ??_C@_05BLPKENEJ@bad?5H@ CONST SEGMENT ??_C@_05BLPKENEJ@bad?5H@ DB 'bad H', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BE@DAPHADHL@bad?5component?5count@ CONST SEGMENT ??_C@_0BE@DAPHADHL@bad?5component?5count@ DB 'bad component count', 00H ; `string' CONST ENDS ; COMDAT ??_C@_09OJDLMMBJ@too?5large@ CONST SEGMENT ??_C@_09OJDLMMBJ@too?5large@ DB 'too large', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07BIDACDEF@0?5width@ CONST SEGMENT ??_C@_07BIDACDEF@0?5width@ DB '0 width', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BB@LNEGOMA@no?5header?5height@ CONST SEGMENT ??_C@_0BB@LNEGOMA@no?5header?5height@ DB 'no header height', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0L@BCINMEBJ@only?58?9bit@ CONST SEGMENT ??_C@_0L@BCINMEBJ@only?58?9bit@ DB 'only 8-bit', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@DOFMJEMP@bad?5SOF?5len@ CONST SEGMENT ??_C@_0M@DOFMJEMP@bad?5SOF?5len@ DB 'bad SOF len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_07EEJOMGGP@bad?5SOS@ CONST SEGMENT ??_C@_07EEJOMGGP@bad?5SOS@ DB 'bad SOS', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@JGMCBLGG@bad?5AC?5huff@ CONST SEGMENT ??_C@_0M@JGMCBLGG@bad?5AC?5huff@ DB 'bad AC huff', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@NOCCBFAC@bad?5DC?5huff@ CONST SEGMENT ??_C@_0M@NOCCBFAC@bad?5DC?5huff@ DB 'bad DC huff', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@GNEHAHOH@bad?5SOS?5len@ CONST SEGMENT ??_C@_0M@GNEHAHOH@bad?5SOS?5len@ DB 'bad SOS len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BI@DHFJCMBA@bad?5SOS?5component?5count@ CONST SEGMENT ??_C@_0BI@DHFJCMBA@bad?5SOS?5component?5count@ DB 'bad SOS component coun' DB 't', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@NNGPHMMK@unknown?5marker@ CONST SEGMENT ??_C@_0P@NNGPHMMK@unknown?5marker@ DB 'unknown marker', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@EENLKPDI@bad?5APP?5len@ CONST SEGMENT ??_C@_0M@EENLKPDI@bad?5APP?5len@ DB 'bad APP len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@CICAFFCH@bad?5COM?5len@ CONST SEGMENT ??_C@_0M@CICAFFCH@bad?5COM?5len@ DB 'bad COM len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0P@JLGKOCGN@bad?5DHT?5header@ CONST SEGMENT ??_C@_0P@JLGKOCGN@bad?5DHT?5header@ DB 'bad DHT header', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@CNHKKDIM@bad?5DQT?5table@ CONST SEGMENT ??_C@_0O@CNHKKDIM@bad?5DQT?5table@ DB 'bad DQT table', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0N@BOFJCHAP@bad?5DQT?5type@ CONST SEGMENT ??_C@_0N@BOFJCHAP@bad?5DQT?5type@ DB 'bad DQT type', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@LPHNODCG@bad?5DRI?5len@ CONST SEGMENT ??_C@_0M@LPHNODCG@bad?5DRI?5len@ DB 'bad DRI len', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BA@KLNDOKJD@expected?5marker@ CONST SEGMENT ??_C@_0BA@KLNDOKJD@expected?5marker@ DB 'expected marker', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ CONST SEGMENT ??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ DB 'can''t merge dc and ac' DB 00H ; `string' CONST ENDS ; COMDAT ??_C@_09IFDKCGFO@bad?5delta@ CONST SEGMENT ??_C@_09IFDKCGFO@bad?5delta@ DB 'bad delta', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BB@IIMLINA@bad?5huffman?5code@ CONST SEGMENT ??_C@_0BB@IIMLINA@bad?5huffman?5code@ DB 'bad huffman code', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BB@FOKGPEKG@bad?5code?5lengths@ CONST SEGMENT ??_C@_0BB@FOKGPEKG@bad?5code?5lengths@ DB 'bad code lengths', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0O@DEFOLMLB@bad?5size?5list@ CONST SEGMENT ??_C@_0O@DEFOLMLB@bad?5size?5list@ DB 'bad size list', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@MHDBFHD@unsupported@ CONST SEGMENT ??_C@_0M@MHDBFHD@unsupported@ DB 'unsupported', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0CB@DDANHPKI@can?8t?5fopen?0?5Unable?5to?5open?5fil@ CONST SEGMENT ??_C@_0CB@DDANHPKI@can?8t?5fopen?0?5Unable?5to?5open?5fil@ DB 'can''t fop' DB 'en, Unable to open file', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0M@JPDHFAGK@can?8t?5fopen@ CONST SEGMENT ??_C@_0M@JPDHFAGK@can?8t?5fopen@ DB 'can''t fopen', 00H ; `string' CONST ENDS ; COMDAT ??_C@_02JDPG@rb@ CONST SEGMENT ??_C@_02JDPG@rb@ DB 'rb', 00H ; `string' CONST ENDS ; COMDAT ??_C@_08NOGIMCHF@outofmem@ CONST SEGMENT ??_C@_08NOGIMCHF@outofmem@ DB 'outofmem', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BD@CBEDEJPH@unknown?5image?5type@ CONST SEGMENT ??_C@_0BD@CBEDEJPH@unknown?5image?5type@ DB 'unknown image type', 00H ; `string' CONST ENDS PUBLIC stbi_zlib_decode_malloc_guesssize_headerflag PUBLIC stbi_load_from_file PUBLIC stbi_load stbi__vertically_flip_on_load_local DD 01H DUP (?) ALIGN 8 stbi__g_failure_reason DQ 01H DUP (?) stbi__unpremultiply_on_load_set DD 01H DUP (?) stbi__de_iphone_flag_local DD 01H DUP (?) stbi__de_iphone_flag_set DD 01H DUP (?) stbi__unpremultiply_on_load_local DD 01H DUP (?) stbi__vertically_flip_on_load_set DD 01H DUP (?) _TLS ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pnm_info DD imagerel stbi__pnm_info DD imagerel stbi__pnm_info+596 DD imagerel $unwind$stbi__pnm_info pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pnm_getinteger DD imagerel stbi__pnm_getinteger DD imagerel stbi__pnm_getinteger+314 DD imagerel $unwind$stbi__pnm_getinteger pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pnm_skip_whitespace DD imagerel stbi__pnm_skip_whitespace DD imagerel stbi__pnm_skip_whitespace+485 DD imagerel $unwind$stbi__pnm_skip_whitespace pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pnm_load DD imagerel stbi__pnm_load DD imagerel stbi__pnm_load+640 DD imagerel $unwind$stbi__pnm_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pnm_test DD imagerel stbi__pnm_test DD imagerel stbi__pnm_test+225 DD imagerel $unwind$stbi__pnm_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_load DD imagerel stbi__hdr_load DD imagerel stbi__hdr_load+2206 DD imagerel $unwind$stbi__hdr_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_convert DD imagerel stbi__hdr_convert DD imagerel stbi__hdr_convert+302 DD imagerel $unwind$stbi__hdr_convert pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_gettoken DD imagerel stbi__hdr_gettoken DD imagerel stbi__hdr_gettoken+409 DD imagerel $unwind$stbi__hdr_gettoken pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_test DD imagerel stbi__hdr_test DD imagerel stbi__hdr_test+283 DD imagerel $unwind$stbi__hdr_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_test_core DD imagerel stbi__hdr_test_core DD imagerel stbi__hdr_test_core+186 DD imagerel $unwind$stbi__hdr_test_core pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_load DD imagerel stbi__gif_load DD imagerel stbi__gif_load+240 DD imagerel $unwind$stbi__gif_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_load_next DD imagerel stbi__gif_load_next DD imagerel stbi__gif_load_next+1803 DD imagerel $unwind$stbi__gif_load_next pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__process_gif_raster DD imagerel stbi__process_gif_raster DD imagerel stbi__process_gif_raster+78 DD imagerel $unwind$stbi__process_gif_raster pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__process_gif_raster DD imagerel stbi__process_gif_raster+78 DD imagerel stbi__process_gif_raster+392 DD imagerel $chain$5$stbi__process_gif_raster pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__process_gif_raster DD imagerel stbi__process_gif_raster+392 DD imagerel stbi__process_gif_raster+1156 DD imagerel $chain$7$stbi__process_gif_raster pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__out_gif_code DD imagerel stbi__out_gif_code DD imagerel stbi__out_gif_code+279 DD imagerel $unwind$stbi__out_gif_code pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_header DD imagerel stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel $unwind$stbi__gif_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel stbi__gif_header+747 DD imagerel $chain$0$stbi__gif_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__gif_header DD imagerel stbi__gif_header+747 DD imagerel stbi__gif_header+769 DD imagerel $chain$1$stbi__gif_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__gif_header DD imagerel stbi__gif_header+769 DD imagerel stbi__gif_header+783 DD imagerel $chain$2$stbi__gif_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__gif_header DD imagerel stbi__gif_header+783 DD imagerel stbi__gif_header+862 DD imagerel $chain$3$stbi__gif_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable+31 DD imagerel $unwind$stbi__gif_parse_colortable pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable+31 DD imagerel stbi__gif_parse_colortable+334 DD imagerel $chain$0$stbi__gif_parse_colortable pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable+334 DD imagerel stbi__gif_parse_colortable+335 DD imagerel $chain$1$stbi__gif_parse_colortable pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_test DD imagerel stbi__gif_test DD imagerel stbi__gif_test+48 DD imagerel $unwind$stbi__gif_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__gif_test_raw DD imagerel stbi__gif_test_raw DD imagerel stbi__gif_test_raw+367 DD imagerel $unwind$stbi__gif_test_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pic_test DD imagerel stbi__pic_test DD imagerel stbi__pic_test+48 DD imagerel $unwind$stbi__pic_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__pic_test DD imagerel stbi__pic_test+48 DD imagerel stbi__pic_test+229 DD imagerel $chain$2$stbi__pic_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__pic_test DD imagerel stbi__pic_test+229 DD imagerel stbi__pic_test+271 DD imagerel $chain$3$stbi__pic_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pic_load DD imagerel stbi__pic_load DD imagerel stbi__pic_load+353 DD imagerel $unwind$stbi__pic_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__pic_load DD imagerel stbi__pic_load+353 DD imagerel stbi__pic_load+584 DD imagerel $chain$1$stbi__pic_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__pic_load DD imagerel stbi__pic_load+584 DD imagerel stbi__pic_load+611 DD imagerel $chain$2$stbi__pic_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pic_load_core DD imagerel stbi__pic_load_core DD imagerel stbi__pic_load_core+1488 DD imagerel $unwind$stbi__pic_load_core pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__readval DD imagerel stbi__readval DD imagerel stbi__readval+269 DD imagerel $unwind$stbi__readval pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pic_test_core DD imagerel stbi__pic_test_core DD imagerel stbi__pic_test_core+233 DD imagerel $unwind$stbi__pic_test_core pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__pic_is4 DD imagerel stbi__pic_is4 DD imagerel stbi__pic_is4+154 DD imagerel $unwind$stbi__pic_is4 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__psd_load DD imagerel stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel $unwind$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel stbi__psd_load+924 DD imagerel $chain$2$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__psd_load DD imagerel stbi__psd_load+924 DD imagerel stbi__psd_load+1015 DD imagerel $chain$4$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__psd_load DD imagerel stbi__psd_load+1015 DD imagerel stbi__psd_load+1265 DD imagerel $chain$5$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__psd_load DD imagerel stbi__psd_load+1265 DD imagerel stbi__psd_load+1278 DD imagerel $chain$6$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__psd_load DD imagerel stbi__psd_load+1278 DD imagerel stbi__psd_load+1300 DD imagerel $chain$7$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$9$stbi__psd_load DD imagerel stbi__psd_load+1300 DD imagerel stbi__psd_load+3196 DD imagerel $chain$9$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$10$stbi__psd_load DD imagerel stbi__psd_load+3196 DD imagerel stbi__psd_load+3238 DD imagerel $chain$10$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$11$stbi__psd_load DD imagerel stbi__psd_load+3238 DD imagerel stbi__psd_load+3287 DD imagerel $chain$11$stbi__psd_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__psd_decode_rle DD imagerel stbi__psd_decode_rle DD imagerel stbi__psd_decode_rle+418 DD imagerel $unwind$stbi__psd_decode_rle pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__psd_test DD imagerel stbi__psd_test DD imagerel stbi__psd_test+84 DD imagerel $unwind$stbi__psd_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__tga_load DD imagerel stbi__tga_load DD imagerel stbi__tga_load+2677 DD imagerel $unwind$stbi__tga_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__tga_read_rgb16 DD imagerel stbi__tga_read_rgb16 DD imagerel stbi__tga_read_rgb16+130 DD imagerel $unwind$stbi__tga_read_rgb16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__tga_test DD imagerel stbi__tga_test DD imagerel stbi__tga_test+156 DD imagerel $unwind$stbi__tga_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__tga_test DD imagerel stbi__tga_test+156 DD imagerel stbi__tga_test+643 DD imagerel $chain$2$stbi__tga_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__tga_test DD imagerel stbi__tga_test+643 DD imagerel stbi__tga_test+693 DD imagerel $chain$3$stbi__tga_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__bmp_load DD imagerel stbi__bmp_load DD imagerel stbi__bmp_load+4870 DD imagerel $unwind$stbi__bmp_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+130 DD imagerel $unwind$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+130 DD imagerel stbi__bmp_parse_header+447 DD imagerel $chain$1$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+447 DD imagerel stbi__bmp_parse_header+557 DD imagerel $chain$2$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+557 DD imagerel stbi__bmp_parse_header+575 DD imagerel $chain$3$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+575 DD imagerel stbi__bmp_parse_header+1376 DD imagerel $chain$5$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+1376 DD imagerel stbi__bmp_parse_header+1421 DD imagerel $chain$6$stbi__bmp_parse_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__bmp_test DD imagerel stbi__bmp_test DD imagerel stbi__bmp_test+275 DD imagerel $unwind$stbi__bmp_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__bmp_test_raw DD imagerel stbi__bmp_test_raw DD imagerel stbi__bmp_test_raw+256 DD imagerel $unwind$stbi__bmp_test_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__png_test DD imagerel stbi__png_test DD imagerel stbi__png_test+48 DD imagerel $unwind$stbi__png_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__png_load DD imagerel stbi__png_load DD imagerel stbi__png_load+385 DD imagerel $unwind$stbi__png_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__do_png DD imagerel stbi__do_png DD imagerel stbi__do_png+353 DD imagerel $unwind$stbi__do_png pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__parse_png_file DD imagerel stbi__parse_png_file DD imagerel stbi__parse_png_file+3874 DD imagerel $unwind$stbi__parse_png_file pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__de_iphone DD imagerel stbi__de_iphone DD imagerel stbi__de_iphone+134 DD imagerel $unwind$stbi__de_iphone pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__de_iphone DD imagerel stbi__de_iphone+134 DD imagerel stbi__de_iphone+256 DD imagerel $chain$0$stbi__de_iphone pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__de_iphone DD imagerel stbi__de_iphone+256 DD imagerel stbi__de_iphone+283 DD imagerel $chain$1$stbi__de_iphone pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__expand_png_palette DD imagerel stbi__expand_png_palette DD imagerel stbi__expand_png_palette+307 DD imagerel $unwind$stbi__expand_png_palette pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__create_png_image DD imagerel stbi__create_png_image DD imagerel stbi__create_png_image+139 DD imagerel $unwind$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__create_png_image DD imagerel stbi__create_png_image+139 DD imagerel stbi__create_png_image+247 DD imagerel $chain$0$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__create_png_image DD imagerel stbi__create_png_image+247 DD imagerel stbi__create_png_image+1003 DD imagerel $chain$2$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__create_png_image DD imagerel stbi__create_png_image+1003 DD imagerel stbi__create_png_image+1026 DD imagerel $chain$3$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__create_png_image DD imagerel stbi__create_png_image+1026 DD imagerel stbi__create_png_image+1041 DD imagerel $chain$5$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__create_png_image DD imagerel stbi__create_png_image+1041 DD imagerel stbi__create_png_image+1080 DD imagerel $chain$6$stbi__create_png_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel $unwind$stbi__create_png_image_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel stbi__create_png_image_raw+437 DD imagerel $chain$0$stbi__create_png_image_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+437 DD imagerel stbi__create_png_image_raw+455 DD imagerel $chain$1$stbi__create_png_image_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+455 DD imagerel stbi__create_png_image_raw+4675 DD imagerel $chain$2$stbi__create_png_image_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+4675 DD imagerel stbi__create_png_image_raw+4808 DD imagerel $chain$3$stbi__create_png_image_raw pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__paeth DD imagerel stbi__paeth DD imagerel stbi__paeth+86 DD imagerel $unwind$stbi__paeth pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__check_png_header DD imagerel stbi__check_png_header DD imagerel stbi__check_png_header+189 DD imagerel $unwind$stbi__check_png_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get_chunk_header DD imagerel stbi__get_chunk_header DD imagerel stbi__get_chunk_header+84 DD imagerel $unwind$stbi__get_chunk_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi_zlib_decode_malloc_guesssize_headerflag DD imagerel $LN16 DD imagerel $LN16+185 DD imagerel $unwind$stbi_zlib_decode_malloc_guesssize_headerflag pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__parse_zlib DD imagerel stbi__parse_zlib DD imagerel stbi__parse_zlib+656 DD imagerel $unwind$stbi__parse_zlib pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__parse_uncompressed_block DD imagerel stbi__parse_uncompressed_block DD imagerel stbi__parse_uncompressed_block+485 DD imagerel $unwind$stbi__parse_uncompressed_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+37 DD imagerel $unwind$stbi__compute_huffman_codes pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+37 DD imagerel stbi__compute_huffman_codes+310 DD imagerel $chain$0$stbi__compute_huffman_codes pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+310 DD imagerel stbi__compute_huffman_codes+773 DD imagerel $chain$2$stbi__compute_huffman_codes pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+773 DD imagerel stbi__compute_huffman_codes+1637 DD imagerel $chain$3$stbi__compute_huffman_codes pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__parse_huffman_block DD imagerel stbi__parse_huffman_block DD imagerel stbi__parse_huffman_block+1067 DD imagerel $unwind$stbi__parse_huffman_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__zexpand DD imagerel stbi__zexpand DD imagerel stbi__zexpand+164 DD imagerel $unwind$stbi__zexpand pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__zexpand DD imagerel stbi__zexpand+164 DD imagerel stbi__zexpand+242 DD imagerel $chain$0$stbi__zexpand pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__zexpand DD imagerel stbi__zexpand+242 DD imagerel stbi__zexpand+284 DD imagerel $chain$2$stbi__zexpand pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode+45 DD imagerel $unwind$stbi__zhuffman_decode pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode+45 DD imagerel stbi__zhuffman_decode+141 DD imagerel $chain$0$stbi__zhuffman_decode pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode+141 DD imagerel stbi__zhuffman_decode+205 DD imagerel $chain$1$stbi__zhuffman_decode pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__zreceive DD imagerel stbi__zreceive DD imagerel stbi__zreceive+28 DD imagerel $unwind$stbi__zreceive pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__zreceive DD imagerel stbi__zreceive+28 DD imagerel stbi__zreceive+129 DD imagerel $chain$0$stbi__zreceive pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__zreceive DD imagerel stbi__zreceive+129 DD imagerel stbi__zreceive+162 DD imagerel $chain$1$stbi__zreceive pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel $unwind$stbi__zbuild_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel stbi__zbuild_huffman+563 DD imagerel $chain$0$stbi__zbuild_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+563 DD imagerel stbi__zbuild_huffman+594 DD imagerel $chain$1$stbi__zbuild_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+594 DD imagerel stbi__zbuild_huffman+633 DD imagerel $chain$2$stbi__zbuild_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+633 DD imagerel stbi__zbuild_huffman+672 DD imagerel $chain$3$stbi__zbuild_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_test DD imagerel stbi__jpeg_test DD imagerel stbi__jpeg_test+274 DD imagerel $unwind$stbi__jpeg_test pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_load DD imagerel stbi__jpeg_load DD imagerel stbi__jpeg_load+285 DD imagerel $unwind$stbi__jpeg_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$load_jpeg_image DD imagerel load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel $unwind$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel load_jpeg_image+252 DD imagerel $chain$0$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$load_jpeg_image DD imagerel load_jpeg_image+252 DD imagerel load_jpeg_image+453 DD imagerel $chain$4$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$load_jpeg_image DD imagerel load_jpeg_image+453 DD imagerel load_jpeg_image+481 DD imagerel $chain$5$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$load_jpeg_image DD imagerel load_jpeg_image+481 DD imagerel load_jpeg_image+2115 DD imagerel $chain$6$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$load_jpeg_image DD imagerel load_jpeg_image+2115 DD imagerel load_jpeg_image+2123 DD imagerel $chain$7$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$8$load_jpeg_image DD imagerel load_jpeg_image+2123 DD imagerel load_jpeg_image+2152 DD imagerel $chain$8$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$9$load_jpeg_image DD imagerel load_jpeg_image+2152 DD imagerel load_jpeg_image+2208 DD imagerel $chain$9$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$10$load_jpeg_image DD imagerel load_jpeg_image+2208 DD imagerel load_jpeg_image+2247 DD imagerel $chain$10$load_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__setup_jpeg DD imagerel stbi__setup_jpeg DD imagerel stbi__setup_jpeg+114 DD imagerel $unwind$stbi__setup_jpeg pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel $unwind$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel stbi__YCbCr_to_RGB_simd+140 DD imagerel $chain$4$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+140 DD imagerel stbi__YCbCr_to_RGB_simd+339 DD imagerel $chain$5$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+339 DD imagerel stbi__YCbCr_to_RGB_simd+367 DD imagerel $chain$6$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+367 DD imagerel stbi__YCbCr_to_RGB_simd+382 DD imagerel $chain$7$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$9$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+382 DD imagerel stbi__YCbCr_to_RGB_simd+630 DD imagerel $chain$9$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$10$stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+630 DD imagerel stbi__YCbCr_to_RGB_simd+647 DD imagerel $chain$10$stbi__YCbCr_to_RGB_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row+36 DD imagerel $unwind$stbi__YCbCr_to_RGB_row pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row+36 DD imagerel stbi__YCbCr_to_RGB_row+278 DD imagerel $chain$1$stbi__YCbCr_to_RGB_row pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row+278 DD imagerel stbi__YCbCr_to_RGB_row+292 DD imagerel $chain$2$stbi__YCbCr_to_RGB_row pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd+89 DD imagerel $unwind$stbi__resample_row_hv_2_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd+89 DD imagerel stbi__resample_row_hv_2_simd+335 DD imagerel $chain$3$stbi__resample_row_hv_2_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd+335 DD imagerel stbi__resample_row_hv_2_simd+507 DD imagerel $chain$4$stbi__resample_row_hv_2_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__resample_row_hv_2 DD imagerel stbi__resample_row_hv_2 DD imagerel stbi__resample_row_hv_2+192 DD imagerel $unwind$stbi__resample_row_hv_2 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__resample_row_h_2 DD imagerel stbi__resample_row_h_2 DD imagerel stbi__resample_row_h_2+226 DD imagerel $unwind$stbi__resample_row_h_2 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2+88 DD imagerel $unwind$stbi__resample_row_v_2 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2+88 DD imagerel stbi__resample_row_v_2+447 DD imagerel $chain$2$stbi__resample_row_v_2 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2+447 DD imagerel stbi__resample_row_v_2+523 DD imagerel $chain$3$stbi__resample_row_v_2 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__decode_jpeg_image DD imagerel stbi__decode_jpeg_image DD imagerel stbi__decode_jpeg_image+667 DD imagerel $unwind$stbi__decode_jpeg_image pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__skip_jpeg_junk_at_end DD imagerel stbi__skip_jpeg_junk_at_end DD imagerel stbi__skip_jpeg_junk_at_end+292 DD imagerel $unwind$stbi__skip_jpeg_junk_at_end pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__decode_jpeg_header DD imagerel stbi__decode_jpeg_header DD imagerel stbi__decode_jpeg_header+896 DD imagerel $unwind$stbi__decode_jpeg_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__process_frame_header DD imagerel stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel $unwind$stbi__process_frame_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel stbi__process_frame_header+546 DD imagerel $chain$0$stbi__process_frame_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__process_frame_header DD imagerel stbi__process_frame_header+546 DD imagerel stbi__process_frame_header+1632 DD imagerel $chain$4$stbi__process_frame_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__process_frame_header DD imagerel stbi__process_frame_header+1632 DD imagerel stbi__process_frame_header+1951 DD imagerel $chain$6$stbi__process_frame_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__process_frame_header DD imagerel stbi__process_frame_header+1951 DD imagerel stbi__process_frame_header+2047 DD imagerel $chain$7$stbi__process_frame_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components+13 DD imagerel $unwind$stbi__free_jpeg_components pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components+13 DD imagerel stbi__free_jpeg_components+127 DD imagerel $chain$2$stbi__free_jpeg_components pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components+127 DD imagerel stbi__free_jpeg_components+135 DD imagerel $chain$3$stbi__free_jpeg_components pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__process_scan_header DD imagerel stbi__process_scan_header DD imagerel stbi__process_scan_header+197 DD imagerel $unwind$stbi__process_scan_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__process_scan_header DD imagerel stbi__process_scan_header+197 DD imagerel stbi__process_scan_header+866 DD imagerel $chain$1$stbi__process_scan_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__process_scan_header DD imagerel stbi__process_scan_header+866 DD imagerel stbi__process_scan_header+961 DD imagerel $chain$3$stbi__process_scan_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__process_scan_header DD imagerel stbi__process_scan_header+961 DD imagerel stbi__process_scan_header+1014 DD imagerel $chain$4$stbi__process_scan_header pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__process_marker DD imagerel stbi__process_marker DD imagerel stbi__process_marker+2780 DD imagerel $unwind$stbi__process_marker pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_finish DD imagerel stbi__jpeg_finish DD imagerel stbi__jpeg_finish+28 DD imagerel $unwind$stbi__jpeg_finish pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__jpeg_finish DD imagerel stbi__jpeg_finish+28 DD imagerel stbi__jpeg_finish+45 DD imagerel $chain$0$stbi__jpeg_finish pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__jpeg_finish DD imagerel stbi__jpeg_finish+45 DD imagerel stbi__jpeg_finish+456 DD imagerel $chain$6$stbi__jpeg_finish pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__jpeg_finish DD imagerel stbi__jpeg_finish+456 DD imagerel stbi__jpeg_finish+461 DD imagerel $chain$7$stbi__jpeg_finish pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$8$stbi__jpeg_finish DD imagerel stbi__jpeg_finish+461 DD imagerel stbi__jpeg_finish+468 DD imagerel $chain$8$stbi__jpeg_finish pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__parse_entropy_coded_data DD imagerel stbi__parse_entropy_coded_data DD imagerel stbi__parse_entropy_coded_data+2061 DD imagerel $unwind$stbi__parse_entropy_coded_data pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get_marker DD imagerel stbi__get_marker DD imagerel stbi__get_marker+33 DD imagerel $unwind$stbi__get_marker pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__get_marker DD imagerel stbi__get_marker+33 DD imagerel stbi__get_marker+168 DD imagerel $chain$0$stbi__get_marker pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__get_marker DD imagerel stbi__get_marker+168 DD imagerel stbi__get_marker+184 DD imagerel $chain$2$stbi__get_marker pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__get_marker DD imagerel stbi__get_marker+184 DD imagerel stbi__get_marker+197 DD imagerel $chain$4$stbi__get_marker pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__idct_simd DD imagerel stbi__idct_simd DD imagerel stbi__idct_simd+2084 DD imagerel $unwind$stbi__idct_simd pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__idct_block DD imagerel stbi__idct_block DD imagerel stbi__idct_block+1555 DD imagerel $unwind$stbi__idct_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_decode_block_prog_ac DD imagerel stbi__jpeg_decode_block_prog_ac DD imagerel stbi__jpeg_decode_block_prog_ac+1795 DD imagerel $unwind$stbi__jpeg_decode_block_prog_ac pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_decode_block_prog_dc DD imagerel stbi__jpeg_decode_block_prog_dc DD imagerel stbi__jpeg_decode_block_prog_dc+891 DD imagerel $unwind$stbi__jpeg_decode_block_prog_dc pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+617 DD imagerel $unwind$stbi__jpeg_decode_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+617 DD imagerel stbi__jpeg_decode_block+790 DD imagerel $chain$0$stbi__jpeg_decode_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+790 DD imagerel stbi__jpeg_decode_block+1389 DD imagerel $chain$4$stbi__jpeg_decode_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+1389 DD imagerel stbi__jpeg_decode_block+1438 DD imagerel $chain$6$stbi__jpeg_decode_block pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_get_bit DD imagerel stbi__jpeg_get_bit DD imagerel stbi__jpeg_get_bit+77 DD imagerel $unwind$stbi__jpeg_get_bit pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_get_bits DD imagerel stbi__jpeg_get_bits DD imagerel stbi__jpeg_get_bits+109 DD imagerel $unwind$stbi__jpeg_get_bits pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__extend_receive DD imagerel stbi__extend_receive DD imagerel stbi__extend_receive+149 DD imagerel $unwind$stbi__extend_receive pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__jpeg_huff_decode DD imagerel stbi__jpeg_huff_decode DD imagerel stbi__jpeg_huff_decode+278 DD imagerel $unwind$stbi__jpeg_huff_decode pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__grow_buffer_unsafe DD imagerel stbi__grow_buffer_unsafe DD imagerel stbi__grow_buffer_unsafe+381 DD imagerel $unwind$stbi__grow_buffer_unsafe pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__build_fast_ac DD imagerel stbi__build_fast_ac DD imagerel stbi__build_fast_ac+218 DD imagerel $unwind$stbi__build_fast_ac pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__build_huffman DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 DD imagerel $unwind$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__build_huffman DD imagerel stbi__build_huffman+96 DD imagerel stbi__build_huffman+302 DD imagerel $chain$1$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__build_huffman DD imagerel stbi__build_huffman+302 DD imagerel stbi__build_huffman+389 DD imagerel $chain$2$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__build_huffman DD imagerel stbi__build_huffman+389 DD imagerel stbi__build_huffman+413 DD imagerel $chain$3$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__build_huffman DD imagerel stbi__build_huffman+413 DD imagerel stbi__build_huffman+459 DD imagerel $chain$4$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__build_huffman DD imagerel stbi__build_huffman+459 DD imagerel stbi__build_huffman+498 DD imagerel $chain$5$stbi__build_huffman pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr+164 DD imagerel $unwind$stbi__hdr_to_ldr pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$7$stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr+164 DD imagerel stbi__hdr_to_ldr+504 DD imagerel $chain$7$stbi__hdr_to_ldr pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$8$stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr+504 DD imagerel stbi__hdr_to_ldr+586 DD imagerel $chain$8$stbi__hdr_to_ldr pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__convert_format16 DD imagerel stbi__convert_format16 DD imagerel stbi__convert_format16+49 DD imagerel $unwind$stbi__convert_format16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__convert_format16 DD imagerel stbi__convert_format16+49 DD imagerel stbi__convert_format16+130 DD imagerel $chain$0$stbi__convert_format16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__convert_format16 DD imagerel stbi__convert_format16+130 DD imagerel stbi__convert_format16+728 DD imagerel $chain$2$stbi__convert_format16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$3$stbi__convert_format16 DD imagerel stbi__convert_format16+728 DD imagerel stbi__convert_format16+747 DD imagerel $chain$3$stbi__convert_format16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__convert_format16 DD imagerel stbi__convert_format16+747 DD imagerel stbi__convert_format16+1248 DD imagerel $chain$5$stbi__convert_format16 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__convert_format DD imagerel stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel $unwind$stbi__convert_format pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$2$stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel stbi__convert_format+1046 DD imagerel $chain$2$stbi__convert_format pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$4$stbi__convert_format DD imagerel stbi__convert_format+1046 DD imagerel stbi__convert_format+1103 DD imagerel $chain$4$stbi__convert_format pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__convert_format DD imagerel stbi__convert_format+1103 DD imagerel stbi__convert_format+1168 DD imagerel $chain$5$stbi__convert_format pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__convert_format DD imagerel stbi__convert_format+1168 DD imagerel stbi__convert_format+1272 DD imagerel $chain$6$stbi__convert_format pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get32le DD imagerel stbi__get32le DD imagerel stbi__get32le+44 DD imagerel $unwind$stbi__get32le pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get16le DD imagerel stbi__get16le DD imagerel stbi__get16le+177 DD imagerel $unwind$stbi__get16le pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get32be DD imagerel stbi__get32be DD imagerel stbi__get32be+44 DD imagerel $unwind$stbi__get32be pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get16be DD imagerel stbi__get16be DD imagerel stbi__get16be+177 DD imagerel $unwind$stbi__get16be pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__getn DD imagerel stbi__getn DD imagerel stbi__getn+197 DD imagerel $unwind$stbi__getn pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__at_eof DD imagerel stbi__at_eof DD imagerel stbi__at_eof+75 DD imagerel $unwind$stbi__at_eof pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__get8 DD imagerel stbi__get8 DD imagerel stbi__get8+62 DD imagerel $unwind$stbi__get8 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$0$stbi__get8 DD imagerel stbi__get8+62 DD imagerel stbi__get8+155 DD imagerel $chain$0$stbi__get8 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$1$stbi__get8 DD imagerel stbi__get8+155 DD imagerel stbi__get8+163 DD imagerel $chain$1$stbi__get8 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__refill_buffer DD imagerel stbi__refill_buffer DD imagerel stbi__refill_buffer+116 DD imagerel $unwind$stbi__refill_buffer pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi_load_from_file DD imagerel $LN9 DD imagerel $LN9+157 DD imagerel $unwind$stbi_load_from_file pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi_load DD imagerel $LN13 DD imagerel $LN13+187 DD imagerel $unwind$stbi_load pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__fopen DD imagerel stbi__fopen DD imagerel stbi__fopen+87 DD imagerel $unwind$stbi__fopen pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__load_and_postprocess_8bit DD imagerel stbi__load_and_postprocess_8bit DD imagerel stbi__load_and_postprocess_8bit+215 DD imagerel $unwind$stbi__load_and_postprocess_8bit pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__vertical_flip DD imagerel stbi__vertical_flip DD imagerel stbi__vertical_flip+58 DD imagerel $unwind$stbi__vertical_flip pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$5$stbi__vertical_flip DD imagerel stbi__vertical_flip+58 DD imagerel stbi__vertical_flip+257 DD imagerel $chain$5$stbi__vertical_flip pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$6$stbi__vertical_flip DD imagerel stbi__vertical_flip+257 DD imagerel stbi__vertical_flip+285 DD imagerel $chain$6$stbi__vertical_flip pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__convert_16_to_8 DD imagerel stbi__convert_16_to_8 DD imagerel stbi__convert_16_to_8+449 DD imagerel $unwind$stbi__convert_16_to_8 pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__load_main DD imagerel stbi__load_main DD imagerel stbi__load_main+2002 DD imagerel $unwind$stbi__load_main pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__stdio_eof DD imagerel stbi__stdio_eof DD imagerel stbi__stdio_eof+49 DD imagerel $unwind$stbi__stdio_eof pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__stdio_skip DD imagerel stbi__stdio_skip DD imagerel stbi__stdio_skip+58 DD imagerel $unwind$stbi__stdio_skip pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__start_callbacks DD imagerel stbi__start_callbacks DD imagerel stbi__start_callbacks+200 DD imagerel $unwind$stbi__start_callbacks pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__sse2_available DD imagerel stbi__sse2_available DD imagerel stbi__sse2_available+29 DD imagerel $unwind$stbi__sse2_available pdata ENDS ; COMDAT pdata pdata SEGMENT $pdata$stbi__cpuid3 DD imagerel stbi__cpuid3 DD imagerel stbi__cpuid3+23 DD imagerel $unwind$stbi__cpuid3 ?invalid_chunk@?BP@??stbi__parse_png_file@@9@9 DB 'XXXX PNG chunk not kno' DB 'wn', 00H ; `stbi__parse_png_file'::`31'::invalid_chunk ORG $+7 stbi__stdio_callbacks DQ FLAT:stbi__stdio_read DQ FLAT:stbi__stdio_skip DQ FLAT:stbi__stdio_eof _DATA ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__cpuid3 DD 020601H DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__sse2_available DD 020601H DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__start_callbacks DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__stdio_skip DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__stdio_eof DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__load_main DD 0a2619H DD 0150114H DD 0e00bf00dH DD 0c007d009H DD 060047005H DD 030025003H DD imagerel __GSHandlerCheck DD 098H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__convert_16_to_8 DD 081401H DD 086414H DD 075414H DD 063414H DD 070103214H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__vertical_flip DD 021H DD imagerel stbi__vertical_flip DD imagerel stbi__vertical_flip+58 DD imagerel $unwind$stbi__vertical_flip xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__vertical_flip DD 0c2321H DD 0107e423H DD 0108d418H DD 01097414H DD 010a6410H DD 010b540cH DD 010c3404H DD imagerel stbi__vertical_flip DD imagerel stbi__vertical_flip+58 DD imagerel $unwind$stbi__vertical_flip xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__vertical_flip DD 042019H DD 010d010eH DD 0c005f007H DD imagerel __GSHandlerCheck DD 0820H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__load_and_postprocess_8bit DD 061b19H DD 0f008b20cH DD 07004e006H DD 030026003H DD imagerel __GSHandlerCheck DD 050H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__fopen DD 011319H DD 06204H DD imagerel __GSHandlerCheck DD 028H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi_load DD 061a19H DD 0e007720bH DD 060047005H DD 030025003H DD imagerel __GSHandlerCheck DD 038H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi_load_from_file DD 072019H DD 024010eH DD 07005e007H DD 050036004H DD 03002H DD imagerel __GSHandlerCheck DD 0110H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__refill_buffer DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__get8 DD 021H DD imagerel stbi__get8 DD imagerel stbi__get8+62 DD imagerel $unwind$stbi__get8 xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__get8 DD 020521H DD 067405H DD imagerel stbi__get8 DD imagerel stbi__get8+62 DD imagerel $unwind$stbi__get8 xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get8 DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__at_eof DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__getn DD 0c1e01H DD 0b741eH DD 0a641eH DD 09541eH DD 08341eH DD 0f01a321eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get16be DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get32be DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get16le DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get32le DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__convert_format DD 021H DD imagerel stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel $unwind$stbi__convert_format xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__convert_format DD 020021H DD 0cf400H DD imagerel stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel $unwind$stbi__convert_format xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__convert_format DD 060021H DD 0cf400H DD 0be400H DD 0a7400H DD imagerel stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel $unwind$stbi__convert_format xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__convert_format DD 067721H DD 0be477H DD 0a7470H DD 0cf405H DD imagerel stbi__convert_format DD imagerel stbi__convert_format+49 DD imagerel $unwind$stbi__convert_format xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__convert_format DD 060c01H DD 0d008320cH DD 06004c006H DD 030025003H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__convert_format16 DD 060021H DD 0af400H DD 09e400H DD 083400H DD imagerel stbi__convert_format16 DD imagerel stbi__convert_format16+49 DD imagerel $unwind$stbi__convert_format16 xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__convert_format16 DD 021H DD imagerel stbi__convert_format16+49 DD imagerel stbi__convert_format16+130 DD imagerel $chain$0$stbi__convert_format16 xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__convert_format16 DD 040c21H DD 0af40cH DD 083405H DD imagerel stbi__convert_format16+49 DD imagerel stbi__convert_format16+130 DD imagerel $chain$0$stbi__convert_format16 xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__convert_format16 DD 020521H DD 09e405H DD imagerel stbi__convert_format16 DD imagerel stbi__convert_format16+49 DD imagerel $unwind$stbi__convert_format16 xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__convert_format16 DD 060d01H DD 0b540dH DD 0c009320dH DD 060067007H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$8$stbi__hdr_to_ldr DD 021H DD imagerel stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr+164 DD imagerel $unwind$stbi__hdr_to_ldr xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__hdr_to_ldr DD 0105821H DD 048858H DD 057848H DD 06683bH DD 0ef433H DD 0fe42bH DD 017d423H DD 016c418H DD 0155408H DD imagerel stbi__hdr_to_ldr DD imagerel stbi__hdr_to_ldr+164 DD imagerel $unwind$stbi__hdr_to_ldr xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_to_ldr DD 040f01H DD 07008f20fH DD 030066007H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__build_huffman DD 040021H DD 0ae400H DD 097400H DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 DD imagerel $unwind$stbi__build_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__build_huffman DD 021H DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 DD imagerel $unwind$stbi__build_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__build_huffman DD 021H DD imagerel stbi__build_huffman+96 DD imagerel stbi__build_huffman+302 DD imagerel $chain$1$stbi__build_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__build_huffman DD 020521H DD 085405H DD imagerel stbi__build_huffman+96 DD imagerel stbi__build_huffman+302 DD imagerel $chain$1$stbi__build_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__build_huffman DD 041021H DD 0ae410H DD 097405H DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 DD imagerel $unwind$stbi__build_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__build_huffman DD 040901H DD 0f0053209H DD 030026003H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__build_fast_ac DD 071501H DD 037415H DD 02340dH DD 045406H DD 06006H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__grow_buffer_unsafe DD 061201H DD 066412H DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_huff_decode DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__extend_receive DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_get_bits DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_get_bit DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__jpeg_decode_block DD 060021H DD 0cd400H DD 0bc400H DD 0a6400H DD imagerel stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+617 DD imagerel $unwind$stbi__jpeg_decode_block xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__jpeg_decode_block DD 061b21H DD 0a641bH DD 0cd405H DD 0bc400H DD imagerel stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+617 DD imagerel $unwind$stbi__jpeg_decode_block xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__jpeg_decode_block DD 020521H DD 0bc405H DD imagerel stbi__jpeg_decode_block DD imagerel stbi__jpeg_decode_block+617 DD imagerel $unwind$stbi__jpeg_decode_block xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_decode_block DD 060c01H DD 0f008320cH DD 07004e006H DD 030025003H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_decode_block_prog_dc DD 0a7401H DD 09f474H DD 08546fH DD 0a340dH DD 0e009320dH DD 060067007H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_decode_block_prog_ac DD 0c7901H DD 04e479H DD 05d474H DD 0c546fH DD 0f0115215H DD 0700dc00fH DD 0300b600cH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__idct_block DD 0b2919H DD 0303417H DD 0260117H DD 0e00ef010H DD 0c00ad00cH DD 060077008H DD 05006H DD imagerel __GSHandlerCheck DD 0120H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__idct_simd DD 0168f01H DD 08f88fH DD 09e887H DD 0ad87fH DD 0bc877H DD 0cb872H DD 0da86dH DD 0e9868H DD 0f8839H DD 010782eH DD 0116829H DD 025010aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__get_marker DD 020021H DD 063400H DD imagerel stbi__get_marker DD imagerel stbi__get_marker+33 DD imagerel $unwind$stbi__get_marker xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__get_marker DD 020021H DD 063400H DD imagerel stbi__get_marker DD imagerel stbi__get_marker+33 DD imagerel $unwind$stbi__get_marker xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__get_marker DD 020521H DD 063405H DD imagerel stbi__get_marker DD imagerel stbi__get_marker+33 DD imagerel $unwind$stbi__get_marker xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get_marker DD 020601H DD 070023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__parse_entropy_coded_data DD 0d3119H DD 025641fH DD 024541fH DD 023341fH DD 01c011fH DD 0e016f018H DD 0c012d014H DD 07010H DD imagerel __GSHandlerCheck DD 0d0H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$8$stbi__jpeg_finish DD 021H DD imagerel stbi__jpeg_finish DD imagerel stbi__jpeg_finish+28 DD imagerel $unwind$stbi__jpeg_finish xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__jpeg_finish DD 021H DD imagerel stbi__jpeg_finish+28 DD imagerel stbi__jpeg_finish+45 DD imagerel $chain$0$stbi__jpeg_finish xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__jpeg_finish DD 0c1f21H DD 04f41fH DD 06c41bH DD 077417H DD 0c6413H DD 0b540fH DD 0a3404H DD imagerel stbi__jpeg_finish+28 DD imagerel stbi__jpeg_finish+45 DD imagerel $chain$0$stbi__jpeg_finish xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__jpeg_finish DD 020421H DD 05d404H DD imagerel stbi__jpeg_finish DD imagerel stbi__jpeg_finish+28 DD imagerel $unwind$stbi__jpeg_finish xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_finish DD 020901H DD 0e0057209H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__process_marker DD 0c2e19H DD 019641fH DD 018541fH DD 017341fH DD 0f018f21fH DD 0d014e016H DD 07010c012H DD imagerel __GSHandlerCheck DD 070H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__process_scan_header DD 021H DD imagerel stbi__process_scan_header DD imagerel stbi__process_scan_header+197 DD imagerel $unwind$stbi__process_scan_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__process_scan_header DD 040021H DD 07e400H DD 065400H DD imagerel stbi__process_scan_header DD imagerel stbi__process_scan_header+197 DD imagerel $unwind$stbi__process_scan_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__process_scan_header DD 040c21H DD 07e40cH DD 065405H DD imagerel stbi__process_scan_header DD imagerel stbi__process_scan_header+197 DD imagerel $unwind$stbi__process_scan_header xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__process_scan_header DD 060f01H DD 09640fH DD 08340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__free_jpeg_components DD 021H DD imagerel stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components+13 DD imagerel $unwind$stbi__free_jpeg_components xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__free_jpeg_components DD 061821H DD 087418H DD 075411H DD 063405H DD imagerel stbi__free_jpeg_components DD imagerel stbi__free_jpeg_components+13 DD imagerel $unwind$stbi__free_jpeg_components xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__free_jpeg_components DD 020601H DD 060023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__process_frame_header DD 021H DD imagerel stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel $unwind$stbi__process_frame_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__process_frame_header DD 060021H DD 0de400H DD 0cd400H DD 0ac400H DD imagerel stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel $unwind$stbi__process_frame_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__process_frame_header DD 061821H DD 0de418H DD 0cd405H DD 0ac400H DD imagerel stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel $unwind$stbi__process_frame_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__process_frame_header DD 020521H DD 0ac405H DD imagerel stbi__process_frame_header DD imagerel stbi__process_frame_header+437 DD imagerel $unwind$stbi__process_frame_header xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__process_frame_header DD 060e01H DD 0f00a320eH DD 060077008H DD 030055006H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__decode_jpeg_header DD 081401H DD 086414H DD 075414H DD 063414H DD 070103214H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__skip_jpeg_junk_at_end DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__decode_jpeg_image DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__resample_row_v_2 DD 021H DD imagerel stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2+88 DD imagerel $unwind$stbi__resample_row_v_2 xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__resample_row_v_2 DD 060f21H DD 04740fH DD 03640aH DD 025405H DD imagerel stbi__resample_row_v_2 DD imagerel stbi__resample_row_v_2+88 DD imagerel $unwind$stbi__resample_row_v_2 xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__resample_row_v_2 DD 010201H DD 03002H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__resample_row_h_2 DD 074001H DD 07440H DD 036434H DD 02342cH DD 0204H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__resample_row_hv_2 DD 053e01H DD 02743eH DD 033406H DD 06006H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__resample_row_hv_2_simd DD 021H DD imagerel stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd+89 DD imagerel $unwind$stbi__resample_row_hv_2_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__resample_row_hv_2_simd DD 061c21H DD 06f41cH DD 05e40cH DD 045405H DD imagerel stbi__resample_row_hv_2_simd DD imagerel stbi__resample_row_hv_2_simd+89 DD imagerel $unwind$stbi__resample_row_hv_2_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__resample_row_hv_2_simd DD 043901H DD 033439H DD 060027003H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__YCbCr_to_RGB_row DD 021H DD imagerel stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row+36 DD imagerel $unwind$stbi__YCbCr_to_RGB_row xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__YCbCr_to_RGB_row DD 041921H DD 04f419H DD 036405H DD imagerel stbi__YCbCr_to_RGB_row DD imagerel stbi__YCbCr_to_RGB_row+36 DD imagerel $unwind$stbi__YCbCr_to_RGB_row xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__YCbCr_to_RGB_row DD 060d01H DD 06540dH DD 05340dH DD 0700be00dH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$10$stbi__YCbCr_to_RGB_simd DD 021H DD imagerel stbi__YCbCr_to_RGB_simd+367 DD imagerel stbi__YCbCr_to_RGB_simd+382 DD imagerel $chain$7$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$9$stbi__YCbCr_to_RGB_simd DD 041721H DD 011e417H DD 0103408H DD imagerel stbi__YCbCr_to_RGB_simd+367 DD imagerel stbi__YCbCr_to_RGB_simd+382 DD imagerel $chain$7$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__YCbCr_to_RGB_simd DD 021H DD imagerel stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel $unwind$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__YCbCr_to_RGB_simd DD 021H DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel stbi__YCbCr_to_RGB_simd+140 DD imagerel $chain$4$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__YCbCr_to_RGB_simd DD 020521H DD 056805H DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel stbi__YCbCr_to_RGB_simd+140 DD imagerel $chain$4$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__YCbCr_to_RGB_simd DD 0a3f21H DD 0b83fH DD 01a831H DD 029822H DD 038813H DD 047805H DD imagerel stbi__YCbCr_to_RGB_simd DD imagerel stbi__YCbCr_to_RGB_simd+59 DD imagerel $unwind$stbi__YCbCr_to_RGB_simd xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__YCbCr_to_RGB_simd DD 060d01H DD 012540dH DD 0f009b20dH DD 060067007H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__setup_jpeg DD 020601H DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$10$load_jpeg_image DD 021H DD imagerel load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel $unwind$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$9$load_jpeg_image DD 0a0021H DD 02fe400H DD 030c400H DD 0317400H DD 0325400H DD 0333400H DD imagerel load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel $unwind$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$8$load_jpeg_image DD 021H DD imagerel load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel $unwind$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$load_jpeg_image DD 021H DD imagerel load_jpeg_image+124 DD imagerel load_jpeg_image+252 DD imagerel $chain$0$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$load_jpeg_image DD 080021H DD 02fe400H DD 0317400H DD 0325400H DD 0333400H DD imagerel load_jpeg_image+124 DD imagerel load_jpeg_image+252 DD imagerel $chain$0$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$load_jpeg_image DD 021H DD imagerel load_jpeg_image+124 DD imagerel load_jpeg_image+252 DD imagerel $chain$0$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$load_jpeg_image DD 082621H DD 02fe426H DD 031741eH DD 0325413H DD 0333408H DD imagerel load_jpeg_image+124 DD imagerel load_jpeg_image+252 DD imagerel $chain$0$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$load_jpeg_image DD 020821H DD 030c408H DD imagerel load_jpeg_image DD imagerel load_jpeg_image+124 DD imagerel $unwind$load_jpeg_image xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$load_jpeg_image DD 051f19H DD 034010dH DD 0d004f006H DD 06002H DD imagerel __GSHandlerCheck DD 0160H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_load DD 0a1a01H DD 0d741aH DD 0c641aH DD 0b541aH DD 0a341aH DD 0e016721aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__jpeg_test DD 065901H DD 083459H DD 09640aH DD 07006520aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__zbuild_huffman DD 021H DD imagerel stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel $unwind$stbi__zbuild_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__zbuild_huffman DD 020021H DD 0206400H DD imagerel stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel $unwind$stbi__zbuild_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__zbuild_huffman DD 021H DD imagerel stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel $unwind$stbi__zbuild_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__zbuild_huffman DD 020821H DD 0206408H DD imagerel stbi__zbuild_huffman DD imagerel stbi__zbuild_huffman+177 DD imagerel $unwind$stbi__zbuild_huffman xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__zbuild_huffman DD 072319H DD 0180111H DD 0e008f00aH DD 050057006H DD 03004H DD imagerel __GSHandlerCheck DD 0b0H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__zreceive DD 021H DD imagerel stbi__zreceive DD imagerel stbi__zreceive+28 DD imagerel $unwind$stbi__zreceive xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__zreceive DD 020521H DD 023405H DD imagerel stbi__zreceive DD imagerel stbi__zreceive+28 DD imagerel $unwind$stbi__zreceive xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__zreceive DD 010201H DD 07002H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__zhuffman_decode DD 021H DD imagerel stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode+45 DD imagerel $unwind$stbi__zhuffman_decode xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__zhuffman_decode DD 020521H DD 063405H DD imagerel stbi__zhuffman_decode DD imagerel stbi__zhuffman_decode+45 DD imagerel $unwind$stbi__zhuffman_decode xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__zhuffman_decode DD 020601H DD 070023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__zexpand DD 020021H DD 066400H DD imagerel stbi__zexpand DD imagerel stbi__zexpand+164 DD imagerel $unwind$stbi__zexpand xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__zexpand DD 020521H DD 066405H DD imagerel stbi__zexpand DD imagerel stbi__zexpand+164 DD imagerel $unwind$stbi__zexpand xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__zexpand DD 040a01H DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__parse_huffman_block DD 0c2b01H DD 08e42bH DD 0b6418H DD 0a5418H DD 093418H DD 0f0143218H DD 07010c012H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__compute_huffman_codes DD 040021H DD 014c7400H DD 014b6400H DD imagerel stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+37 DD imagerel $unwind$stbi__compute_huffman_codes xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__compute_huffman_codes DD 049b21H DD 014b649bH DD 014c7408H DD imagerel stbi__compute_huffman_codes+37 DD imagerel stbi__compute_huffman_codes+310 DD imagerel $chain$0$stbi__compute_huffman_codes xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__compute_huffman_codes DD 020821H DD 014de408H DD imagerel stbi__compute_huffman_codes DD imagerel stbi__compute_huffman_codes+37 DD imagerel $unwind$stbi__compute_huffman_codes xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__compute_huffman_codes DD 072219H DD 01440110H DD 0d007f009H DD 05003c005H DD 03002H DD imagerel __GSHandlerCheck DD 0a10H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__parse_uncompressed_block DD 040a01H DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__parse_zlib DD 081501H DD 087415H DD 076415H DD 063415H DD 0e0113215H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi_zlib_decode_malloc_guesssize_headerflag DD 062419H DD 02070112H DD 060047005H DD 030025003H DD imagerel __GSHandlerCheck DD 01020H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__get_chunk_header DD 060f01H DD 07640fH DD 06340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__check_png_header DD 060f01H DD 07640fH DD 06340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__paeth DD 020501H DD 013405H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__create_png_image_raw DD 021H DD imagerel stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel $unwind$stbi__create_png_image_raw xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__create_png_image_raw DD 020021H DD 01fd400H DD imagerel stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel $unwind$stbi__create_png_image_raw xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__create_png_image_raw DD 021H DD imagerel stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel $unwind$stbi__create_png_image_raw xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__create_png_image_raw DD 020821H DD 01fd408H DD imagerel stbi__create_png_image_raw DD imagerel stbi__create_png_image_raw+248 DD imagerel $unwind$stbi__create_png_image_raw xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__create_png_image_raw DD 091601H DD 0160116H DD 0e00df00fH DD 07009c00bH DD 050076008H DD 03006H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__create_png_image DD 020021H DD 0236400H DD imagerel stbi__create_png_image DD imagerel stbi__create_png_image+139 DD imagerel $unwind$stbi__create_png_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__create_png_image DD 060021H DD 021f400H DD 022d400H DD 0236400H DD imagerel stbi__create_png_image DD imagerel stbi__create_png_image+139 DD imagerel $unwind$stbi__create_png_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__create_png_image DD 021H DD imagerel stbi__create_png_image+139 DD imagerel stbi__create_png_image+247 DD imagerel $chain$0$stbi__create_png_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__create_png_image DD 041321H DD 021f413H DD 022d408H DD imagerel stbi__create_png_image+139 DD imagerel stbi__create_png_image+247 DD imagerel $chain$0$stbi__create_png_image xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__create_png_image DD 020821H DD 0236408H DD imagerel stbi__create_png_image DD imagerel stbi__create_png_image+139 DD imagerel $unwind$stbi__create_png_image xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__create_png_image DD 072201H DD 0240122H DD 0c019e01bH DD 050167017H DD 03015H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__expand_png_palette DD 0a1801H DD 0a6418H DD 095418H DD 083418H DD 0f0143218H DD 07010e012H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__de_iphone DD 021H DD imagerel stbi__de_iphone DD imagerel stbi__de_iphone+134 DD imagerel $unwind$stbi__de_iphone xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__de_iphone DD 020421H DD 03404H DD imagerel stbi__de_iphone DD imagerel stbi__de_iphone+134 DD imagerel $unwind$stbi__de_iphone xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__de_iphone DD 010401H DD 0204H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__parse_png_file DD 0d3e19H DD 029b742dH DD 029a642dH DD 0299342dH DD 0292012dH DD 0e016f018H DD 0c012d014H DD 05010H DD imagerel __GSHandlerCheck DD 01480H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__do_png DD 0c1e01H DD 0d741eH DD 0c641eH DD 0b541eH DD 0a341eH DD 0f01a521eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__png_load DD 071c19H DD 0f009c20dH DD 07005e007H DD 050036004H DD 03002H DD imagerel __GSHandlerCheck DD 058H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__png_test DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__bmp_test_raw DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__bmp_test DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__bmp_parse_header DD 021H DD imagerel stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+130 DD imagerel $unwind$stbi__bmp_parse_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__bmp_parse_header DD 060021H DD 0af400H DD 09e400H DD 085400H DD imagerel stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+130 DD imagerel $unwind$stbi__bmp_parse_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__bmp_parse_header DD 021H DD imagerel stbi__bmp_parse_header+130 DD imagerel stbi__bmp_parse_header+447 DD imagerel $chain$1$stbi__bmp_parse_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__bmp_parse_header DD 020521H DD 09e405H DD imagerel stbi__bmp_parse_header+130 DD imagerel stbi__bmp_parse_header+447 DD imagerel $chain$1$stbi__bmp_parse_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__bmp_parse_header DD 040d21H DD 0af40dH DD 085405H DD imagerel stbi__bmp_parse_header DD imagerel stbi__bmp_parse_header+130 DD imagerel $unwind$stbi__bmp_parse_header xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__bmp_parse_header DD 040801H DD 070043208H DD 030026003H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__bmp_load DD 0b2601H DD 0a43426H DD 09c0126H DD 0e01df01fH DD 0c019d01bH DD 060167017H DD 05015H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__tga_test DD 021H DD imagerel stbi__tga_test DD imagerel stbi__tga_test+156 DD imagerel $unwind$stbi__tga_test xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__tga_test DD 020521H DD 0af405H DD imagerel stbi__tga_test DD imagerel stbi__tga_test+156 DD imagerel $unwind$stbi__tga_test xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__tga_test DD 085101H DD 096451H DD 08544cH DD 0e0053209H DD 030027003H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__tga_read_rgb16 DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__tga_load DD 0a2619H DD 0130114H DD 0e00bf00dH DD 0c007d009H DD 060047005H DD 030025003H DD imagerel __GSHandlerCheck DD 088H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__psd_test DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__psd_decode_rle DD 0c1e01H DD 0b741eH DD 0a641eH DD 09541eH DD 08341eH DD 0f01a321eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$11$stbi__psd_load DD 020021H DD 0e6400H DD imagerel stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel $unwind$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$10$stbi__psd_load DD 060021H DD 0af400H DD 0be400H DD 0e6400H DD imagerel stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel $unwind$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$9$stbi__psd_load DD 0c0021H DD 0af400H DD 0be400H DD 0cd400H DD 0dc400H DD 0e6400H DD 0125400H DD imagerel stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel $unwind$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__psd_load DD 021H DD imagerel stbi__psd_load+157 DD imagerel stbi__psd_load+924 DD imagerel $chain$2$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$6$stbi__psd_load DD 021H DD imagerel stbi__psd_load+924 DD imagerel stbi__psd_load+1015 DD imagerel $chain$4$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__psd_load DD 020521H DD 0cd405H DD imagerel stbi__psd_load+924 DD imagerel stbi__psd_load+1015 DD imagerel $chain$4$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$4$stbi__psd_load DD 041421H DD 0dc414H DD 0125408H DD imagerel stbi__psd_load+157 DD imagerel stbi__psd_load+924 DD imagerel $chain$2$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__psd_load DD 066521H DD 0af465H DD 0be45dH DD 0e6405H DD imagerel stbi__psd_load DD imagerel stbi__psd_load+157 DD imagerel $unwind$stbi__psd_load xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__psd_load DD 031501H DD 07011e215H DD 03010H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pic_is4 DD 060f01H DD 07640fH DD 06340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pic_test_core DD 081401H DD 086414H DD 075414H DD 063414H DD 070103214H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__readval DD 0a1a01H DD 09741aH DD 08641aH DD 07541aH DD 06341aH DD 0e016321aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pic_load_core DD 0d5219H DD 0106452H DD 0115441H DD 01a3432H DD 0120113H DD 0e00af00cH DD 0c006d008H DD 07004H DD imagerel __GSHandlerCheck DD 078H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__pic_load DD 021H DD imagerel stbi__pic_load DD imagerel stbi__pic_load+353 DD imagerel $unwind$stbi__pic_load xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__pic_load DD 040d21H DD 0be40dH DD 0c5405H DD imagerel stbi__pic_load DD imagerel stbi__pic_load+353 DD imagerel $unwind$stbi__pic_load xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pic_load DD 071d19H DD 0f00ac20eH DD 0c006d008H DD 060037004H DD 03002H DD imagerel __GSHandlerCheck DD 040H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__pic_test DD 021H DD imagerel stbi__pic_test DD imagerel stbi__pic_test+48 DD imagerel $unwind$stbi__pic_test xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__pic_test DD 061421H DD 086414H DD 0ac40fH DD 097405H DD imagerel stbi__pic_test DD imagerel stbi__pic_test+48 DD imagerel $unwind$stbi__pic_test xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pic_test DD 060e01H DD 0b340eH DD 0f00a320eH DD 05006e008H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_test_raw DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_test DD 020601H DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__gif_parse_colortable DD 021H DD imagerel stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable+31 DD imagerel $unwind$stbi__gif_parse_colortable xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__gif_parse_colortable DD 020521H DD 087405H DD imagerel stbi__gif_parse_colortable DD imagerel stbi__gif_parse_colortable+31 DD imagerel $unwind$stbi__gif_parse_colortable xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_parse_colortable DD 081c01H DD 0a541cH DD 09341cH DD 0f018321cH DD 06014e016H xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$3$stbi__gif_header DD 021H DD imagerel stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel $unwind$stbi__gif_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$2$stbi__gif_header DD 020021H DD 06e400H DD imagerel stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel $unwind$stbi__gif_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$1$stbi__gif_header DD 021H DD imagerel stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel $unwind$stbi__gif_header xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$0$stbi__gif_header DD 020521H DD 06e405H DD imagerel stbi__gif_header DD imagerel stbi__gif_header+396 DD imagerel $unwind$stbi__gif_header xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_header DD 081501H DD 097415H DD 086415H DD 073415H DD 0f0113215H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__out_gif_code DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$7$stbi__process_gif_raster DD 0c0021H DD 06f400H DD 07e400H DD 08c400H DD 097400H DD 0a6400H DD 0f5400H DD imagerel stbi__process_gif_raster DD imagerel stbi__process_gif_raster+78 DD imagerel $unwind$stbi__process_gif_raster xdata ENDS ; COMDAT xdata xdata SEGMENT $chain$5$stbi__process_gif_raster DD 0c4421H DD 06f444H DD 07e438H DD 08c431H DD 097425H DD 0a6416H DD 0f5405H DD imagerel stbi__process_gif_raster DD imagerel stbi__process_gif_raster+78 DD imagerel $unwind$stbi__process_gif_raster xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__process_gif_raster DD 030801H DD 0d004a208H DD 03002H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_load_next DD 0c2101H DD 0c6421H DD 0b5421H DD 0a3421H DD 0f01d3221H DD 0d019e01bH DD 07015c017H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__gif_load DD 082819H DD 011170116H DD 0e007f009H DD 060047005H DD 030025003H DD imagerel __GSHandlerCheck DD 088a0H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_test_core DD 060f01H DD 07640fH DD 06340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_test DD 081501H DD 087415H DD 076415H DD 063415H DD 0e0113215H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_gettoken DD 0a1801H DD 0a6418H DD 095418H DD 083418H DD 0f0143218H DD 07010e012H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_convert DD 060f01H DD 07640fH DD 06340fH DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__hdr_load DD 0a2d19H DD 08f011cH DD 0e00bf00dH DD 0c007d009H DD 060047005H DD 050023003H DD imagerel __GSHandlerCheck DD 0460H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pnm_test DD 040a01H DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pnm_load DD 0c1e01H DD 0d741eH DD 0c641eH DD 0b541eH DD 0a341eH DD 0f01a521eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pnm_skip_whitespace DD 0c1e01H DD 0b741eH DD 0a641eH DD 09541eH DD 08341eH DD 0f01a321eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pnm_getinteger DD 0c1e01H DD 0b741eH DD 0a641eH DD 09541eH DD 08341eH DD 0f01a321eH DD 0c016e018H xdata ENDS ; COMDAT xdata xdata SEGMENT $unwind$stbi__pnm_info DD 071c19H DD 0f009620dH DD 07005e007H DD 050036004H DD 03002H DD imagerel __GSHandlerCheck DD 028H ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__cpuid3 _TEXT SEGMENT stbi__cpuid3 PROC ; COMDAT ; 185 : { 00000 40 53 push rbx 00002 48 83 ec 10 sub rsp, 16 ; 186 : int info[4]; ; 187 : __cpuid(info, 1); 00006 b8 01 00 00 00 mov eax, 1 0000b 33 c9 xor ecx, ecx 0000d 0f a2 cpuid ; 188 : return info[3]; 0000f 8b c2 mov eax, edx ; 189 : } 00011 48 83 c4 10 add rsp, 16 00015 5b pop rbx 00016 c3 ret 0 stbi__cpuid3 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__sse2_available _TEXT SEGMENT stbi__sse2_available PROC ; COMDAT ; 207 : { 00000 40 53 push rbx 00002 48 83 ec 10 sub rsp, 16 ; 187 : __cpuid(info, 1); 00006 33 c9 xor ecx, ecx 00008 b8 01 00 00 00 mov eax, 1 0000d 0f a2 cpuid ; 208 : int info3 = stbi__cpuid3(); ; 209 : return ((info3 >> 26) & 1) != 0; 0000f c1 fa 1a sar edx, 26 00012 83 e2 01 and edx, 1 00015 8b c2 mov eax, edx ; 210 : } 00017 48 83 c4 10 add rsp, 16 0001b 5b pop rbx 0001c c3 ret 0 stbi__sse2_available ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__start_callbacks _TEXT SEGMENT s$ = 48 c$dead$ = 56 user$ = 64 stbi__start_callbacks PROC ; COMDAT ; 288 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 289 : s->io = *c; 0000a 0f 10 05 00 00 00 00 movups xmm0, XMMWORD PTR stbi__stdio_callbacks ; 294 : s->img_buffer = s->img_buffer_original = s->buffer_start; 00011 48 8d 79 38 lea rdi, QWORD PTR [rcx+56] 00015 49 8b c0 mov rax, r8 00018 48 8b d9 mov rbx, rcx ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 0001b 41 b8 80 00 00 00 mov r8d, 128 ; 00000080H ; 289 : s->io = *c; 00021 0f 11 41 10 movups XMMWORD PTR [rcx+16], xmm0 ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 00025 48 8b d7 mov rdx, rdi ; 289 : s->io = *c; 00028 f2 0f 10 05 10 00 00 00 movsd xmm0, QWORD PTR stbi__stdio_callbacks+16 00030 f2 0f 11 41 20 movsd QWORD PTR [rcx+32], xmm0 ; 290 : s->io_user_data = user; 00035 48 89 41 28 mov QWORD PTR [rcx+40], rax ; 291 : s->buflen = sizeof(s->buffer_start); 00039 c7 41 34 80 00 00 00 mov DWORD PTR [rcx+52], 128 ; 00000080H ; 292 : s->read_from_callbacks = 1; 00040 c7 41 30 01 00 00 00 mov DWORD PTR [rcx+48], 1 ; 293 : s->callback_already_read = 0; 00047 c7 81 b8 00 00 00 00 00 00 00 mov DWORD PTR [rcx+184], 0 ; 294 : s->img_buffer = s->img_buffer_original = s->buffer_start; 00051 48 89 b9 d0 00 00 00 mov QWORD PTR [rcx+208], rdi 00058 48 89 b9 c0 00 00 00 mov QWORD PTR [rcx+192], rdi ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 0005f 48 8b c8 mov rcx, rax 00062 ff 53 10 call QWORD PTR [rbx+16] ; 1060 : s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); 00065 8b 8b c0 00 00 00 mov ecx, DWORD PTR [rbx+192] 0006b 2b 8b d0 00 00 00 sub ecx, DWORD PTR [rbx+208] 00071 01 8b b8 00 00 00 add DWORD PTR [rbx+184], ecx 00077 48 89 bb c0 00 00 00 mov QWORD PTR [rbx+192], rdi ; 1061 : if (n == 0) { 0007e 85 c0 test eax, eax 00080 75 23 jne SHORT $LN4@stbi__star ; 1062 : // at end of file, treat same as if from memory, but need to handle case ; 1063 : // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file ; 1064 : s->read_from_callbacks = 0; 00082 89 43 30 mov DWORD PTR [rbx+48], eax ; 1065 : s->img_buffer = s->buffer_start; ; 1066 : s->img_buffer_end = s->buffer_start + 1; 00085 48 8d 43 39 lea rax, QWORD PTR [rbx+57] 00089 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax ; 1067 : *s->img_buffer = 0; 00090 c6 07 00 mov BYTE PTR [rdi], 0 ; 295 : stbi__refill_buffer(s); ; 296 : s->img_buffer_original_end = s->img_buffer_end; 00093 48 89 83 d8 00 00 00 mov QWORD PTR [rbx+216], rax ; 297 : } 0009a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0009f 48 83 c4 20 add rsp, 32 ; 00000020H 000a3 5f pop rdi 000a4 c3 ret 0 $LN4@stbi__star: ; 1071 : s->img_buffer_end = s->buffer_start + n; 000a5 48 63 c8 movsxd rcx, eax 000a8 48 83 c1 38 add rcx, 56 ; 00000038H 000ac 48 03 cb add rcx, rbx 000af 48 89 8b c8 00 00 00 mov QWORD PTR [rbx+200], rcx ; 295 : stbi__refill_buffer(s); ; 296 : s->img_buffer_original_end = s->img_buffer_end; 000b6 48 89 8b d8 00 00 00 mov QWORD PTR [rbx+216], rcx ; 297 : } 000bd 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000c2 48 83 c4 20 add rsp, 32 ; 00000020H 000c6 5f pop rdi 000c7 c3 ret 0 stbi__start_callbacks ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__stdio_read _TEXT SEGMENT user$ = 8 data$ = 16 size$ = 24 stbi__stdio_read PROC ; COMDAT ; 302 : { 00000 48 8b c2 mov rax, rdx ; 303 : return (int)fread(data, 1, size, (FILE*)user); 00003 4d 63 c0 movsxd r8, r8d 00006 4c 8b c9 mov r9, rcx 00009 ba 01 00 00 00 mov edx, 1 0000e 48 8b c8 mov rcx, rax 00011 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_fread stbi__stdio_read ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__stdio_skip _TEXT SEGMENT user$ = 48 n$ = 56 stbi__stdio_skip PROC ; COMDAT ; 307 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 308 : int ch; ; 309 : fseek((FILE*)user, n, SEEK_CUR); 00006 41 b8 01 00 00 00 mov r8d, 1 0000c 48 8b d9 mov rbx, rcx 0000f ff 15 00 00 00 00 call QWORD PTR __imp_fseek ; 310 : ch = fgetc((FILE*)user); /* have to read a byte to reset feof()'s flag */ 00015 48 8b cb mov rcx, rbx 00018 ff 15 00 00 00 00 call QWORD PTR __imp_fgetc ; 311 : if (ch != EOF) { 0001e 83 f8 ff cmp eax, -1 00021 74 11 je SHORT $LN2@stbi__stdi ; 312 : ungetc(ch, (FILE*)user); /* push byte back onto stream if valid. */ 00023 48 8b d3 mov rdx, rbx 00026 8b c8 mov ecx, eax ; 313 : } ; 314 : } 00028 48 83 c4 20 add rsp, 32 ; 00000020H 0002c 5b pop rbx ; 312 : ungetc(ch, (FILE*)user); /* push byte back onto stream if valid. */ 0002d 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_ungetc $LN2@stbi__stdi: ; 313 : } ; 314 : } 00034 48 83 c4 20 add rsp, 32 ; 00000020H 00038 5b pop rbx 00039 c3 ret 0 stbi__stdio_skip ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__stdio_eof _TEXT SEGMENT user$ = 48 stbi__stdio_eof PROC ; COMDAT ; 317 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H 00006 48 8b d9 mov rbx, rcx ; 318 : return feof((FILE*)user) || ferror((FILE*)user); 00009 ff 15 00 00 00 00 call QWORD PTR __imp_feof 0000f 85 c0 test eax, eax 00011 75 13 jne SHORT $LN3@stbi__stdi 00013 48 8b cb mov rcx, rbx 00016 ff 15 00 00 00 00 call QWORD PTR __imp_ferror 0001c 85 c0 test eax, eax 0001e 75 06 jne SHORT $LN3@stbi__stdi ; 319 : } 00020 48 83 c4 20 add rsp, 32 ; 00000020H 00024 5b pop rbx 00025 c3 ret 0 $LN3@stbi__stdi: ; 318 : return feof((FILE*)user) || ferror((FILE*)user); 00026 b8 01 00 00 00 mov eax, 1 ; 319 : } 0002b 48 83 c4 20 add rsp, 32 ; 00000020H 0002f 5b pop rbx 00030 c3 ret 0 stbi__stdio_eof ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__start_file _TEXT SEGMENT s$ = 8 f$ = 16 stbi__start_file PROC ; COMDAT ; 330 : stbi__start_callbacks(s, &stbi__stdio_callbacks, (void*)f); 00000 4c 8b c2 mov r8, rdx 00003 e9 00 00 00 00 jmp stbi__start_callbacks stbi__start_file ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__rewind _TEXT SEGMENT s$ = 8 stbi__rewind PROC ; COMDAT ; 339 : // conceptually rewind SHOULD rewind to the beginning of the stream, ; 340 : // but we just rewind to the beginning of the initial buffer, because ; 341 : // we only use it after doing 'test', which only ever looks at at most 92 bytes ; 342 : s->img_buffer = s->img_buffer_original; 00000 48 8b 81 d0 00 00 00 mov rax, QWORD PTR [rcx+208] 00007 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0000e 48 8b 81 d8 00 00 00 mov rax, QWORD PTR [rcx+216] 00015 48 89 81 c8 00 00 00 mov QWORD PTR [rcx+200], rax ; 344 : } 0001c c3 ret 0 stbi__rewind ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__err _TEXT SEGMENT str$ = 8 stbi__err PROC ; COMDAT ; 431 : stbi__g_failure_reason = str; 00000 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00006 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0000f 41 b8 00 00 00 00 mov r8d, OFFSET FLAT:stbi__g_failure_reason 00015 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00019 49 89 0c 00 mov QWORD PTR [r8+rax], rcx ; 432 : return 0; 0001d 33 c0 xor eax, eax ; 433 : } 0001f c3 ret 0 stbi__err ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__malloc _TEXT SEGMENT size$ = 8 stbi__malloc PROC ; COMDAT ; 438 : return STBI_MALLOC(size); 00000 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_malloc stbi__malloc ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__addsizes_valid _TEXT SEGMENT a$ = 8 b$ = 16 stbi__addsizes_valid PROC ; COMDAT ; 455 : if (b < 0) return 0; 00000 33 c0 xor eax, eax 00002 44 8b c1 mov r8d, ecx 00005 85 d2 test edx, edx 00007 78 0d js SHORT $LN1@stbi__adds ; 456 : // now 0 <= b <= INT_MAX, hence also ; 457 : // 0 <= INT_MAX - b <= INTMAX. ; 458 : // And "a + b <= INT_MAX" (which might overflow) is the ; 459 : // same as a <= INT_MAX - b (no overflow) ; 460 : return a <= INT_MAX - b; 00009 b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 0000e 2b ca sub ecx, edx 00010 44 3b c1 cmp r8d, ecx 00013 0f 9e c0 setle al $LN1@stbi__adds: ; 461 : } 00016 c3 ret 0 stbi__addsizes_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__mul2sizes_valid _TEXT SEGMENT a$ = 8 b$ = 16 stbi__mul2sizes_valid PROC ; COMDAT ; 466 : { 00000 44 8b c2 mov r8d, edx 00003 44 8b c9 mov r9d, ecx ; 467 : if (a < 0 || b < 0) return 0; 00006 85 c9 test ecx, ecx 00008 78 21 js SHORT $LN3@stbi__mul2 0000a 85 d2 test edx, edx 0000c 78 1d js SHORT $LN3@stbi__mul2 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000e 75 06 jne SHORT $LN4@stbi__mul2 00010 b8 01 00 00 00 mov eax, 1 ; 471 : } 00015 c3 ret 0 $LN4@stbi__mul2: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00016 33 d2 xor edx, edx 00018 33 c9 xor ecx, ecx 0001a b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0001f 41 f7 f0 div r8d 00022 44 3b c8 cmp r9d, eax 00025 0f 9e c1 setle cl 00028 8b c1 mov eax, ecx ; 471 : } 0002a c3 ret 0 $LN3@stbi__mul2: ; 467 : if (a < 0 || b < 0) return 0; 0002b 33 c0 xor eax, eax ; 471 : } 0002d c3 ret 0 stbi__mul2sizes_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__mad2sizes_valid _TEXT SEGMENT a$ = 8 b$ = 16 add$ = 24 stbi__mad2sizes_valid PROC ; COMDAT ; 476 : { 00000 44 8b d2 mov r10d, edx ; 467 : if (a < 0 || b < 0) return 0; 00003 85 c9 test ecx, ecx 00005 78 2f js SHORT $LN3@stbi__mad2 00007 85 d2 test edx, edx 00009 78 2b js SHORT $LN3@stbi__mad2 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000b 41 b9 ff ff ff 7f mov r9d, 2147483647 ; 7fffffffH 00011 74 0c je SHORT $LN13@stbi__mad2 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00013 33 d2 xor edx, edx 00015 41 8b c1 mov eax, r9d 00018 41 f7 f2 div r10d ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0001b 3b c8 cmp ecx, eax 0001d 7f 17 jg SHORT $LN3@stbi__mad2 $LN13@stbi__mad2: ; 455 : if (b < 0) return 0; 0001f 45 85 c0 test r8d, r8d 00022 78 12 js SHORT $LN3@stbi__mad2 ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 00024 41 0f af ca imul ecx, r10d ; 460 : return a <= INT_MAX - b; 00028 45 2b c8 sub r9d, r8d ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0002b 41 3b c9 cmp ecx, r9d 0002e 7f 06 jg SHORT $LN3@stbi__mad2 00030 b8 01 00 00 00 mov eax, 1 ; 478 : } 00035 c3 ret 0 $LN3@stbi__mad2: ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 00036 33 c0 xor eax, eax ; 478 : } 00038 c3 ret 0 stbi__mad2sizes_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__mad3sizes_valid _TEXT SEGMENT a$ = 8 b$ = 16 c$ = 24 add$ = 32 stbi__mad3sizes_valid PROC ; COMDAT ; 483 : { 00000 44 8b da mov r11d, edx ; 467 : if (a < 0 || b < 0) return 0; 00003 85 c9 test ecx, ecx 00005 78 4a js SHORT $LN3@stbi__mad3 00007 85 d2 test edx, edx 00009 78 46 js SHORT $LN3@stbi__mad3 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000b 41 ba ff ff ff 7f mov r10d, 2147483647 ; 7fffffffH 00011 74 0c je SHORT $LN19@stbi__mad3 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00013 33 d2 xor edx, edx 00015 41 8b c2 mov eax, r10d 00018 41 f7 f3 div r11d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0001b 3b c8 cmp ecx, eax 0001d 7f 32 jg SHORT $LN3@stbi__mad3 $LN19@stbi__mad3: 0001f 41 0f af cb imul ecx, r11d ; 467 : if (a < 0 || b < 0) return 0; 00023 85 c9 test ecx, ecx 00025 78 2a js SHORT $LN3@stbi__mad3 00027 45 85 c0 test r8d, r8d 0002a 78 25 js SHORT $LN3@stbi__mad3 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0002c 74 0c je SHORT $LN18@stbi__mad3 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0002e 33 d2 xor edx, edx 00030 41 8b c2 mov eax, r10d 00033 41 f7 f0 div r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00036 3b c8 cmp ecx, eax 00038 7f 17 jg SHORT $LN3@stbi__mad3 $LN18@stbi__mad3: ; 455 : if (b < 0) return 0; 0003a 45 85 c9 test r9d, r9d 0003d 78 12 js SHORT $LN3@stbi__mad3 ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0003f 41 0f af c8 imul ecx, r8d ; 460 : return a <= INT_MAX - b; 00043 45 2b d1 sub r10d, r9d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00046 41 3b ca cmp ecx, r10d 00049 7f 06 jg SHORT $LN3@stbi__mad3 0004b b8 01 00 00 00 mov eax, 1 ; 485 : stbi__addsizes_valid(a * b * c, add); ; 486 : } 00050 c3 ret 0 $LN3@stbi__mad3: ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00051 33 c0 xor eax, eax ; 485 : stbi__addsizes_valid(a * b * c, add); ; 486 : } 00053 c3 ret 0 stbi__mad3sizes_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__mad4sizes_valid _TEXT SEGMENT a$ = 8 b$ = 16 c$ = 24 d$ = 32 add$dead$ = 40 stbi__mad4sizes_valid PROC ; COMDAT ; 491 : { 00000 44 8b d2 mov r10d, edx ; 467 : if (a < 0 || b < 0) return 0; 00003 85 c9 test ecx, ecx 00005 78 54 js SHORT $LN3@stbi__mad4 00007 85 d2 test edx, edx 00009 78 50 js SHORT $LN3@stbi__mad4 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000b 74 0e je SHORT $LN25@stbi__mad4 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0000d 33 d2 xor edx, edx 0000f b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00014 41 f7 f2 div r10d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00017 3b c8 cmp ecx, eax 00019 7f 40 jg SHORT $LN3@stbi__mad4 $LN25@stbi__mad4: 0001b 41 0f af ca imul ecx, r10d ; 467 : if (a < 0 || b < 0) return 0; 0001f 85 c9 test ecx, ecx 00021 78 38 js SHORT $LN3@stbi__mad4 00023 45 85 c0 test r8d, r8d 00026 78 33 js SHORT $LN3@stbi__mad4 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00028 74 0e je SHORT $LN24@stbi__mad4 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0002a 33 d2 xor edx, edx 0002c b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00031 41 f7 f0 div r8d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00034 3b c8 cmp ecx, eax 00036 7f 23 jg SHORT $LN3@stbi__mad4 $LN24@stbi__mad4: 00038 41 0f af c8 imul ecx, r8d ; 467 : if (a < 0 || b < 0) return 0; 0003c 85 c9 test ecx, ecx 0003e 78 1b js SHORT $LN3@stbi__mad4 00040 45 85 c9 test r9d, r9d 00043 78 16 js SHORT $LN3@stbi__mad4 ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00045 74 0e je SHORT $LN23@stbi__mad4 ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00047 33 d2 xor edx, edx 00049 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0004e 41 f7 f1 div r9d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00051 3b c8 cmp ecx, eax 00053 7f 06 jg SHORT $LN3@stbi__mad4 $LN23@stbi__mad4: 00055 b8 01 00 00 00 mov eax, 1 ; 493 : stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); ; 494 : } 0005a c3 ret 0 $LN3@stbi__mad4: ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0005b 33 c0 xor eax, eax ; 493 : stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); ; 494 : } 0005d c3 ret 0 stbi__mad4sizes_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__malloc_mad2 _TEXT SEGMENT a$ = 8 b$ = 16 add$ = 24 stbi__malloc_mad2 PROC ; COMDAT ; 500 : { 00000 44 8b ca mov r9d, edx 00003 44 8b d9 mov r11d, ecx ; 467 : if (a < 0 || b < 0) return 0; 00006 85 c9 test ecx, ecx 00008 78 44 js SHORT $LN19@stbi__mall 0000a 85 d2 test edx, edx 0000c 78 40 js SHORT $LN19@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000e 41 ba ff ff ff 7f mov r10d, 2147483647 ; 7fffffffH 00014 75 09 jne SHORT $LN11@stbi__mall 00016 45 0f af cb imul r9d, r11d 0001a 41 8b c9 mov ecx, r9d 0001d eb 14 jmp SHORT $LN20@stbi__mall $LN11@stbi__mall: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0001f 33 d2 xor edx, edx 00021 41 8b c2 mov eax, r10d 00024 41 f7 f1 div r9d ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 00027 41 8b c9 mov ecx, r9d 0002a 41 0f af cb imul ecx, r11d 0002e 44 3b d8 cmp r11d, eax 00031 7f 1b jg SHORT $LN19@stbi__mall $LN20@stbi__mall: ; 455 : if (b < 0) return 0; 00033 45 85 c0 test r8d, r8d 00036 78 16 js SHORT $LN19@stbi__mall ; 456 : // now 0 <= b <= INT_MAX, hence also ; 457 : // 0 <= INT_MAX - b <= INTMAX. ; 458 : // And "a + b <= INT_MAX" (which might overflow) is the ; 459 : // same as a <= INT_MAX - b (no overflow) ; 460 : return a <= INT_MAX - b; 00038 45 2b d0 sub r10d, r8d ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0003b 41 3b ca cmp ecx, r10d 0003e 7f 0e jg SHORT $LN19@stbi__mall ; 502 : return stbi__malloc(a * b + add); 00040 42 8d 04 01 lea eax, DWORD PTR [rcx+r8] 00044 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 00047 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_malloc $LN19@stbi__mall: ; 501 : if (!stbi__mad2sizes_valid(a, b, add)) return NULL; 0004e 33 c0 xor eax, eax ; 503 : } 00050 c3 ret 0 stbi__malloc_mad2 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__malloc_mad3 _TEXT SEGMENT a$ = 8 b$ = 16 c$ = 24 add$ = 32 stbi__malloc_mad3 PROC ; COMDAT ; 507 : { 00000 44 8b da mov r11d, edx ; 467 : if (a < 0 || b < 0) return 0; 00003 85 c9 test ecx, ecx 00005 78 57 js SHORT $LN23@stbi__mall 00007 85 d2 test edx, edx 00009 78 53 js SHORT $LN23@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000b 41 ba ff ff ff 7f mov r10d, 2147483647 ; 7fffffffH 00011 74 0c je SHORT $LN25@stbi__mall ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00013 33 d2 xor edx, edx 00015 41 8b c2 mov eax, r10d 00018 41 f7 f3 div r11d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0001b 3b c8 cmp ecx, eax 0001d 7f 3f jg SHORT $LN23@stbi__mall $LN25@stbi__mall: 0001f 41 0f af cb imul ecx, r11d ; 467 : if (a < 0 || b < 0) return 0; 00023 85 c9 test ecx, ecx 00025 78 37 js SHORT $LN23@stbi__mall 00027 45 85 c0 test r8d, r8d 0002a 78 32 js SHORT $LN23@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0002c 74 0c je SHORT $LN24@stbi__mall ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0002e 33 d2 xor edx, edx 00030 41 8b c2 mov eax, r10d 00033 41 f7 f0 div r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00036 3b c8 cmp ecx, eax 00038 7f 24 jg SHORT $LN23@stbi__mall $LN24@stbi__mall: ; 455 : if (b < 0) return 0; 0003a 45 85 c9 test r9d, r9d 0003d 78 1f js SHORT $LN23@stbi__mall ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0003f 8b c1 mov eax, ecx ; 460 : return a <= INT_MAX - b; 00041 45 2b d1 sub r10d, r9d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00044 41 0f af c0 imul eax, r8d 00048 41 3b c2 cmp eax, r10d 0004b 7f 11 jg SHORT $LN23@stbi__mall ; 509 : return stbi__malloc(a * b * c + add); 0004d 41 0f af c8 imul ecx, r8d 00051 41 03 c9 add ecx, r9d 00054 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 00057 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_malloc $LN23@stbi__mall: ; 508 : if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; 0005e 33 c0 xor eax, eax ; 510 : } 00060 c3 ret 0 stbi__malloc_mad3 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__malloc_mad4 _TEXT SEGMENT a$ = 8 b$ = 16 c$ = 24 d$ = 32 add$dead$ = 40 stbi__malloc_mad4 PROC ; COMDAT ; 514 : { 00000 44 8b d2 mov r10d, edx ; 467 : if (a < 0 || b < 0) return 0; 00003 85 c9 test ecx, ecx 00005 78 65 js SHORT $LN28@stbi__mall 00007 85 d2 test edx, edx 00009 78 61 js SHORT $LN28@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0000b 74 0e je SHORT $LN31@stbi__mall ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0000d 33 d2 xor edx, edx 0000f b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00014 41 f7 f2 div r10d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00017 3b c8 cmp ecx, eax 00019 7f 51 jg SHORT $LN28@stbi__mall $LN31@stbi__mall: 0001b 41 0f af ca imul ecx, r10d ; 467 : if (a < 0 || b < 0) return 0; 0001f 85 c9 test ecx, ecx 00021 78 49 js SHORT $LN28@stbi__mall 00023 45 85 c0 test r8d, r8d 00026 78 44 js SHORT $LN28@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00028 74 0e je SHORT $LN30@stbi__mall ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0002a 33 d2 xor edx, edx 0002c b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00031 41 f7 f0 div r8d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00034 3b c8 cmp ecx, eax 00036 7f 34 jg SHORT $LN28@stbi__mall $LN30@stbi__mall: 00038 44 8b d1 mov r10d, ecx 0003b 45 0f af d0 imul r10d, r8d ; 467 : if (a < 0 || b < 0) return 0; 0003f 45 85 d2 test r10d, r10d 00042 78 28 js SHORT $LN28@stbi__mall 00044 45 85 c9 test r9d, r9d 00047 78 23 js SHORT $LN28@stbi__mall ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00049 74 0f je SHORT $LN2@stbi__mall ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0004b 33 d2 xor edx, edx 0004d b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00052 41 f7 f1 div r9d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00055 44 3b d0 cmp r10d, eax 00058 7f 12 jg SHORT $LN28@stbi__mall $LN2@stbi__mall: ; 516 : return stbi__malloc(a * b * c * d + add); 0005a 41 0f af c8 imul ecx, r8d 0005e 41 0f af c9 imul ecx, r9d 00062 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 00065 48 ff 25 00 00 00 00 rex_jmp QWORD PTR __imp_malloc $LN28@stbi__mall: ; 515 : if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; 0006c 33 c0 xor eax, eax ; 517 : } 0006e c3 ret 0 stbi__malloc_mad4 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__addints_valid _TEXT SEGMENT a$ = 8 b$ = 16 stbi__addints_valid PROC ; COMDAT ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 00000 44 8b c1 mov r8d, ecx 00003 8b c2 mov eax, edx 00005 41 f7 d0 not r8d 00008 f7 d0 not eax 0000a 44 33 c0 xor r8d, eax 0000d 44 8b c9 mov r9d, ecx 00010 79 06 jns SHORT $LN2@stbi__addi 00012 b8 01 00 00 00 mov eax, 1 ; 526 : } 00017 c3 ret 0 $LN2@stbi__addi: ; 524 : if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. 00018 45 85 c9 test r9d, r9d 0001b 79 16 jns SHORT $LN3@stbi__addi 0001d 85 d2 test edx, edx 0001f 79 12 jns SHORT $LN3@stbi__addi 00021 b8 00 00 00 80 mov eax, -2147483648 ; ffffffff80000000H 00026 2b c2 sub eax, edx 00028 33 d2 xor edx, edx 0002a 44 3b c8 cmp r9d, eax 0002d 0f 9d c2 setge dl ; 526 : } 00030 8b c2 mov eax, edx 00032 c3 ret 0 $LN3@stbi__addi: ; 525 : return a <= INT_MAX - b; 00033 b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 00038 2b ca sub ecx, edx 0003a 33 d2 xor edx, edx 0003c 44 3b c9 cmp r9d, ecx 0003f 0f 9e c2 setle dl ; 526 : } 00042 8b c2 mov eax, edx 00044 c3 ret 0 stbi__addints_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__mul2shorts_valid _TEXT SEGMENT a$ = 8 b$ = 16 stbi__mul2shorts_valid PROC ; COMDAT ; 530 : { 00000 44 0f bf c2 movsx r8d, dx ; 531 : if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow 00004 41 8d 40 01 lea eax, DWORD PTR [r8+1] 00008 66 83 f8 01 cmp ax, 1 0000c 76 40 jbe SHORT $LN3@stbi__mul2 ; 532 : if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid 0000e 44 0f bf c9 movsx r9d, cx 00012 45 8b d0 mov r10d, r8d 00015 66 41 33 c8 xor cx, r8w 00019 66 0f ba e1 0f bt cx, 15 0001e 72 14 jb SHORT $LN4@stbi__mul2 00020 b8 ff 7f 00 00 mov eax, 32767 ; 00007fffH 00025 99 cdq 00026 41 f7 fa idiv r10d 00029 33 c9 xor ecx, ecx $LN8@stbi__mul2: ; 535 : } 0002b 44 3b c8 cmp r9d, eax 0002e 0f 9e c1 setle cl 00031 8b c1 mov eax, ecx 00033 c3 ret 0 $LN4@stbi__mul2: ; 533 : if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN 00034 b8 00 80 ff ff mov eax, -32768 ; ffffffffffff8000H 00039 33 c9 xor ecx, ecx 0003b 99 cdq 0003c 41 f7 fa idiv r10d 0003f 66 45 85 c0 test r8w, r8w 00043 78 e6 js SHORT $LN8@stbi__mul2 ; 534 : return a >= SHRT_MIN / b; 00045 44 3b c8 cmp r9d, eax 00048 0f 9d c1 setge cl 0004b 8b c1 mov eax, ecx ; 535 : } 0004d c3 ret 0 $LN3@stbi__mul2: ; 531 : if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow 0004e b8 01 00 00 00 mov eax, 1 ; 535 : } 00053 c3 ret 0 stbi__mul2shorts_valid ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__load_main _TEXT SEGMENT x$GSCopy$1$ = 64 ri$GSCopy$1$ = 80 comp$GSCopy$1$ = 88 tv1050 = 96 info$11 = 96 p$12 = 112 __$ArrayPad$ = 152 s$ = 240 x$ = 248 y$ = 256 comp$ = 264 req_comp$ = 272 ri$ = 280 bpc$dead$ = 288 stbi__load_main PROC ; COMDAT ; 589 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 54 push r12 00007 41 55 push r13 00009 41 56 push r14 0000b 41 57 push r15 0000d 48 81 ec a8 00 00 00 sub rsp, 168 ; 000000a8H 00014 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0001b 48 33 c4 xor rax, rsp 0001e 48 89 84 24 98 00 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00026 48 8b 84 24 18 01 00 00 mov rax, QWORD PTR ri$[rsp] ; 590 : memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields ; 591 : ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed ; 592 : ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order 0002e 45 33 e4 xor r12d, r12d 00031 8b ac 24 10 01 00 00 mov ebp, DWORD PTR req_comp$[rsp] 00038 4d 8b e9 mov r13, r9 0003b 4c 89 4c 24 58 mov QWORD PTR comp$GSCopy$1$[rsp], r9 00040 4d 8b f8 mov r15, r8 00043 48 8b da mov rbx, rdx 00046 48 89 54 24 40 mov QWORD PTR x$GSCopy$1$[rsp], rdx 0004b 48 c7 00 08 00 00 00 mov QWORD PTR [rax], 8 00052 48 8b f9 mov rdi, rcx 00055 44 89 60 08 mov DWORD PTR [rax+8], r12d 00059 48 89 44 24 50 mov QWORD PTR ri$GSCopy$1$[rsp], rax ; 4825 : r = stbi__check_png_header(s); 0005e e8 00 00 00 00 call stbi__check_png_header ; 342 : s->img_buffer = s->img_buffer_original; 00063 48 8b 8f d0 00 00 00 mov rcx, QWORD PTR [rdi+208] 0006a 48 8d b7 c0 00 00 00 lea rsi, QWORD PTR [rdi+192] ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00071 48 8b 97 d8 00 00 00 mov rdx, QWORD PTR [rdi+216] 00078 4c 8d b7 c8 00 00 00 lea r14, QWORD PTR [rdi+200] 0007f 48 89 0e mov QWORD PTR [rsi], rcx 00082 49 89 16 mov QWORD PTR [r14], rdx ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 00085 85 c0 test eax, eax 00087 0f 84 5d 01 00 00 je $LN2@stbi__load ; 4818 : p.s = s; 0008d 48 89 7c 24 70 mov QWORD PTR p$12[rsp], rdi ; 4785 : void* result = NULL; 00092 41 8b dc mov ebx, r12d ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); 00095 83 fd 04 cmp ebp, 4 00098 0f 87 1f 01 00 00 ja $LN22@stbi__load ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { 0009e 44 8b c5 mov r8d, ebp 000a1 48 8d 4c 24 70 lea rcx, QWORD PTR p$12[rsp] 000a6 33 d2 xor edx, edx 000a8 e8 00 00 00 00 call stbi__parse_png_file 000ad 85 c0 test eax, eax 000af 0f 84 99 00 00 00 je $LN163@stbi__load ; 4788 : if (p->depth <= 8) 000b5 8b 84 24 90 00 00 00 mov eax, DWORD PTR p$12[rsp+32] 000bc 83 f8 08 cmp eax, 8 000bf 7f 07 jg SHORT $LN24@stbi__load ; 4789 : ri->bits_per_channel = 8; 000c1 41 8d 44 24 08 lea eax, QWORD PTR [r12+8] 000c6 eb 09 jmp SHORT $LN27@stbi__load $LN24@stbi__load: ; 4790 : else if (p->depth == 16) 000c8 83 f8 10 cmp eax, 16 000cb 0f 85 bf 00 00 00 jne $LN26@stbi__load $LN27@stbi__load: ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; 000d1 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 000d6 89 01 mov DWORD PTR [rcx], eax 000d8 48 8b 9c 24 88 00 00 00 mov rbx, QWORD PTR p$12[rsp+24] ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { 000e0 48 8b 4c 24 70 mov rcx, QWORD PTR p$12[rsp] 000e5 4c 89 a4 24 88 00 00 00 mov QWORD PTR p$12[rsp+24], r12 000ed 85 ed test ebp, ebp 000ef 74 41 je SHORT $LN31@stbi__load 000f1 8b 51 0c mov edx, DWORD PTR [rcx+12] 000f4 3b ea cmp ebp, edx 000f6 74 3a je SHORT $LN31@stbi__load ; 4797 : if (ri->bits_per_channel == 8) 000f8 44 8b 09 mov r9d, DWORD PTR [rcx] 000fb 83 f8 08 cmp eax, 8 000fe 8b 41 04 mov eax, DWORD PTR [rcx+4] 00101 44 8b c5 mov r8d, ebp 00104 89 44 24 20 mov DWORD PTR [rsp+32], eax 00108 48 8b cb mov rcx, rbx 0010b 75 07 jne SHORT $LN29@stbi__load ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 0010d e8 00 00 00 00 call stbi__convert_format 00112 eb 05 jmp SHORT $LN209@stbi__load $LN29@stbi__load: ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 00114 e8 00 00 00 00 call stbi__convert_format16 $LN209@stbi__load: ; 4801 : p->s->img_out_n = req_comp; 00119 48 8b d8 mov rbx, rax 0011c 48 8b 44 24 70 mov rax, QWORD PTR p$12[rsp] 00121 89 68 0c mov DWORD PTR [rax+12], ebp ; 4802 : if (result == NULL) return result; 00124 48 85 db test rbx, rbx 00127 0f 84 b5 00 00 00 je $LN20@stbi__load 0012d 48 8b 4c 24 70 mov rcx, QWORD PTR p$12[rsp] $LN31@stbi__load: ; 4803 : } ; 4804 : *x = p->s->img_x; 00132 8b 01 mov eax, DWORD PTR [rcx] 00134 4c 8b 74 24 40 mov r14, QWORD PTR x$GSCopy$1$[rsp] 00139 41 89 06 mov DWORD PTR [r14], eax ; 4805 : *y = p->s->img_y; 0013c 8b 41 04 mov eax, DWORD PTR [rcx+4] 0013f 41 89 07 mov DWORD PTR [r15], eax ; 4806 : if (n) *n = p->s->img_n; 00142 4d 85 ed test r13, r13 00145 74 07 je SHORT $LN163@stbi__load 00147 8b 41 08 mov eax, DWORD PTR [rcx+8] 0014a 41 89 45 00 mov DWORD PTR [r13], eax $LN163@stbi__load: ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; 0014e 48 8b 8c 24 88 00 00 00 mov rcx, QWORD PTR p$12[rsp+24] 00156 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; 0015c 48 8b 8c 24 80 00 00 00 mov rcx, QWORD PTR p$12[rsp+16] 00164 4c 89 a4 24 88 00 00 00 mov QWORD PTR p$12[rsp+24], r12 0016c ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4810 : STBI_FREE(p->idata); p->idata = NULL; 00172 48 8b 4c 24 78 mov rcx, QWORD PTR p$12[rsp+8] 00177 4c 89 a4 24 80 00 00 00 mov QWORD PTR p$12[rsp+16], r12 0017f ff 15 00 00 00 00 call QWORD PTR __imp_free ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 00185 48 8b c3 mov rax, rbx ; 4812 : return result; 00188 4c 8b e3 mov r12, rbx ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 0018b e9 1e 06 00 00 jmp $LN1@stbi__load $LN26@stbi__load: ; 431 : stbi__g_failure_reason = str; 00190 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00199 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 0019f 41 bd 00 00 00 00 mov r13d, OFFSET FLAT:stbi__g_failure_reason ; 431 : stbi__g_failure_reason = str; 001a5 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 001a9 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 001b0 49 89 44 15 00 mov QWORD PTR [r13+rdx], rax 001b5 49 8b c4 mov rax, r12 001b8 e9 f1 05 00 00 jmp $LN1@stbi__load $LN22@stbi__load: ; 431 : stbi__g_failure_reason = str; 001bd 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001c6 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 001cc 41 bd 00 00 00 00 mov r13d, OFFSET FLAT:stbi__g_failure_reason ; 431 : stbi__g_failure_reason = str; 001d2 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 001d6 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0N@KBPNPPBJ@bad?5req_comp@ ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 001dd 49 89 44 15 00 mov QWORD PTR [r13+rdx], rax $LN20@stbi__load: 001e2 49 8b c4 mov rax, r12 001e5 e9 c4 05 00 00 jmp $LN1@stbi__load $LN2@stbi__load: ; 1077 : if (s->img_buffer < s->img_buffer_end) 001ea 48 3b ca cmp rcx, rdx 001ed 73 09 jae SHORT $LN47@stbi__load ; 1078 : return *s->img_buffer++; 001ef 0f b6 11 movzx edx, BYTE PTR [rcx] 001f2 48 8d 41 01 lea rax, QWORD PTR [rcx+1] 001f6 eb 1b jmp SHORT $LN211@stbi__load $LN47@stbi__load: ; 1079 : if (s->read_from_callbacks) { 001f8 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 001fc 0f 84 f5 00 00 00 je $LN153@stbi__load ; 1080 : stbi__refill_buffer(s); 00202 48 8b cf mov rcx, rdi 00205 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0020a 48 8b 06 mov rax, QWORD PTR [rsi] 0020d 0f b6 10 movzx edx, BYTE PTR [rax] 00210 48 ff c0 inc rax $LN211@stbi__load: ; 4870 : if (stbi__get8(s) != 'B') return 0; 00213 48 89 06 mov QWORD PTR [rsi], rax 00216 80 fa 42 cmp dl, 66 ; 00000042H 00219 0f 85 d8 00 00 00 jne $LN153@stbi__load ; 1077 : if (s->img_buffer < s->img_buffer_end) 0021f 49 3b 06 cmp rax, QWORD PTR [r14] 00222 72 15 jb SHORT $LN212@stbi__load ; 1079 : if (s->read_from_callbacks) { 00224 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00228 0f 84 c9 00 00 00 je $LN153@stbi__load ; 1080 : stbi__refill_buffer(s); 0022e 48 8b cf mov rcx, rdi 00231 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00236 48 8b 06 mov rax, QWORD PTR [rsi] $LN212@stbi__load: ; 4871 : if (stbi__get8(s) != 'M') return 0; 00239 0f b6 08 movzx ecx, BYTE PTR [rax] 0023c 48 ff c0 inc rax 0023f 48 89 06 mov QWORD PTR [rsi], rax 00242 80 f9 4d cmp cl, 77 ; 0000004dH 00245 0f 85 ac 00 00 00 jne $LN153@stbi__load ; 1186 : stbi__uint32 z = stbi__get16le(s); 0024b 48 8b cf mov rcx, rdi 0024e e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00253 48 8b cf mov rcx, rdi 00256 e8 00 00 00 00 call stbi__get16le ; 4873 : stbi__get16le(s); // discard reserved 0025b 48 8b cf mov rcx, rdi 0025e e8 00 00 00 00 call stbi__get16le ; 4874 : stbi__get16le(s); // discard reserved 00263 48 8b cf mov rcx, rdi 00266 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 0026b 48 8b cf mov rcx, rdi 0026e e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00273 48 8b cf mov rcx, rdi 00276 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 0027b 48 8b cf mov rcx, rdi 0027e e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00283 48 8b cf mov rcx, rdi 00286 8b d8 mov ebx, eax 00288 e8 00 00 00 00 call stbi__get16le 0028d c1 e0 10 shl eax, 16 00290 03 c3 add eax, ebx ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); 00292 83 f8 38 cmp eax, 56 ; 00000038H 00295 77 10 ja SHORT $LN158@stbi__load 00297 48 ba 00 10 00 00 00 01 00 01 mov rdx, 72058693549559808 ; 0100010000001000H 002a1 48 0f a3 c2 bt rdx, rax 002a5 72 0d jb SHORT $LN44@stbi__load $LN158@stbi__load: 002a7 83 f8 6c cmp eax, 108 ; 0000006cH 002aa 74 08 je SHORT $LN44@stbi__load 002ac 41 8b cc mov ecx, r12d 002af 83 f8 7c cmp eax, 124 ; 0000007cH 002b2 75 05 jne SHORT $LN45@stbi__load $LN44@stbi__load: 002b4 b9 01 00 00 00 mov ecx, 1 $LN45@stbi__load: ; 342 : s->img_buffer = s->img_buffer_original; 002b9 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] 002c0 48 89 06 mov QWORD PTR [rsi], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 002c3 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 002ca 49 89 06 mov QWORD PTR [r14], rax ; 599 : #endif ; 600 : #ifndef STBI_NO_BMP ; 601 : if (stbi__bmp_test(s)) return stbi__bmp_load(s, x, y, comp, req_comp, ri); 002cd 85 c9 test ecx, ecx 002cf 74 3c je SHORT $LN164@stbi__load 002d1 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 002d6 4d 8b cd mov r9, r13 002d9 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 002de 4d 8b c7 mov r8, r15 002e1 48 89 4c 24 28 mov QWORD PTR [rsp+40], rcx 002e6 48 8b cf mov rcx, rdi 002e9 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 002ed e8 00 00 00 00 call stbi__bmp_load 002f2 e9 b7 04 00 00 jmp $LN1@stbi__load $LN153@stbi__load: ; 6141 : int r = stbi__gif_test_raw(s); 002f7 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] 002fe 48 89 06 mov QWORD PTR [rsi], rax 00301 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 00308 49 89 06 mov QWORD PTR [r14], rax 0030b eb 05 jmp SHORT $LN3@stbi__load $LN164@stbi__load: ; 599 : #endif ; 600 : #ifndef STBI_NO_BMP ; 601 : if (stbi__bmp_test(s)) return stbi__bmp_load(s, x, y, comp, req_comp, ri); 0030d 48 8b 5c 24 40 mov rbx, QWORD PTR x$GSCopy$1$[rsp] $LN3@stbi__load: ; 6141 : int r = stbi__gif_test_raw(s); 00312 48 8b cf mov rcx, rdi 00315 e8 00 00 00 00 call stbi__gif_test_raw ; 342 : s->img_buffer = s->img_buffer_original; 0031a 48 8b 8f d0 00 00 00 mov rcx, QWORD PTR [rdi+208] 00321 48 89 0e mov QWORD PTR [rsi], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00324 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] 0032b 49 89 0e mov QWORD PTR [r14], rcx ; 602 : #endif ; 603 : #ifndef STBI_NO_GIF ; 604 : if (stbi__gif_test(s)) return stbi__gif_load(s, x, y, comp, req_comp, ri); 0032e 48 8b cf mov rcx, rdi 00331 85 c0 test eax, eax 00333 74 17 je SHORT $LN4@stbi__load 00335 4d 8b cd mov r9, r13 00338 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 0033c 4d 8b c7 mov r8, r15 0033f 48 8b d3 mov rdx, rbx 00342 e8 00 00 00 00 call stbi__gif_load 00347 e9 62 04 00 00 jmp $LN1@stbi__load $LN4@stbi__load: ; 1168 : stbi__uint32 z = stbi__get16be(s); 0034c e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00351 48 8b cf mov rcx, rdi 00354 8b d8 mov ebx, eax 00356 e8 00 00 00 00 call stbi__get16be ; 342 : s->img_buffer = s->img_buffer_original; 0035b 48 8b 8f d0 00 00 00 mov rcx, QWORD PTR [rdi+208] ; 1169 : return (z << 16) + stbi__get16be(s); 00362 c1 e3 10 shl ebx, 16 ; 342 : s->img_buffer = s->img_buffer_original; 00365 48 89 0e mov QWORD PTR [rsi], rcx ; 1169 : return (z << 16) + stbi__get16be(s); 00368 03 c3 add eax, ebx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0036a 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] 00371 49 89 0e mov QWORD PTR [r14], rcx ; 605 : #endif ; 606 : #ifndef STBI_NO_PSD ; 607 : if (stbi__psd_test(s)) return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); 00374 3d 53 50 42 38 cmp eax, 943870035 ; 38425053H 00379 75 26 jne SHORT $LN5@stbi__load 0037b 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 00380 4d 8b cd mov r9, r13 00383 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 00388 4d 8b c7 mov r8, r15 0038b 48 89 4c 24 28 mov QWORD PTR [rsp+40], rcx 00390 48 8b cf mov rcx, rdi 00393 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 00397 e8 00 00 00 00 call stbi__psd_load 0039c e9 0d 04 00 00 jmp $LN1@stbi__load $LN5@stbi__load: ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) 003a1 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_04KBFEPHFH@S?$IA?v4@ 003a8 48 8b cf mov rcx, rdi 003ab e8 00 00 00 00 call stbi__pic_is4 003b0 85 c0 test eax, eax 003b2 0f 84 af 00 00 00 je $LN156@stbi__load ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) 003b8 bb 54 00 00 00 mov ebx, 84 ; 00000054H 003bd 0f 1f 00 npad 3 $LL77@stbi__load: ; 1077 : if (s->img_buffer < s->img_buffer_end) 003c0 48 8b 06 mov rax, QWORD PTR [rsi] 003c3 49 3b 06 cmp rax, QWORD PTR [r14] 003c6 73 08 jae SHORT $LN82@stbi__load ; 1078 : return *s->img_buffer++; 003c8 48 ff c0 inc rax 003cb 48 89 06 mov QWORD PTR [rsi], rax 003ce eb 14 jmp SHORT $LN75@stbi__load $LN82@stbi__load: ; 1079 : if (s->read_from_callbacks) { 003d0 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 003d4 74 0e je SHORT $LN75@stbi__load ; 1080 : stbi__refill_buffer(s); 003d6 48 8b cf mov rcx, rdi 003d9 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003de 48 ff 06 inc QWORD PTR [rsi] 003e1 48 8b 06 mov rax, QWORD PTR [rsi] $LN75@stbi__load: ; 5901 : for (i = 0; i < 84; ++i) 003e4 48 83 eb 01 sub rbx, 1 003e8 75 d6 jne SHORT $LL77@stbi__load 003ea 49 8b dc mov rbx, r12 003ed 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_04ELNJHLFH@PICT@ $LL88@stbi__load: ; 1077 : if (s->img_buffer < s->img_buffer_end) 003f4 49 3b 06 cmp rax, QWORD PTR [r14] 003f7 73 0b jae SHORT $LN92@stbi__load ; 1078 : return *s->img_buffer++; 003f9 0f b6 08 movzx ecx, BYTE PTR [rax] 003fc 48 ff c0 inc rax 003ff 48 89 06 mov QWORD PTR [rsi], rax 00402 eb 25 jmp SHORT $LN91@stbi__load $LN92@stbi__load: ; 1079 : if (s->read_from_callbacks) { 00404 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00408 74 1d je SHORT $LN93@stbi__load ; 1080 : stbi__refill_buffer(s); 0040a 48 8b cf mov rcx, rdi 0040d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00412 48 8b 06 mov rax, QWORD PTR [rsi] 00415 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_04ELNJHLFH@PICT@ 0041c 0f b6 08 movzx ecx, BYTE PTR [rax] 0041f 48 ff c0 inc rax 00422 48 89 06 mov QWORD PTR [rsi], rax 00425 eb 02 jmp SHORT $LN91@stbi__load $LN93@stbi__load: ; 1082 : } ; 1083 : return 0; 00427 32 c9 xor cl, cl $LN91@stbi__load: ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) 00429 3a 0c 13 cmp cl, BYTE PTR [rbx+rdx] 0042c 75 39 jne SHORT $LN156@stbi__load ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) 0042e 48 ff c3 inc rbx 00431 48 83 fb 04 cmp rbx, 4 00435 7c bd jl SHORT $LL88@stbi__load ; 5907 : return 1; 00437 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] ; 608 : #else ; 609 : STBI_NOTUSED(bpc); ; 610 : #endif ; 611 : #ifndef STBI_NO_PIC ; 612 : if (stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); 0043e 4d 8b cd mov r9, r13 00441 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 00446 4d 8b c7 mov r8, r15 ; 5907 : return 1; 00449 48 89 06 mov QWORD PTR [rsi], rax ; 608 : #else ; 609 : STBI_NOTUSED(bpc); ; 610 : #endif ; 611 : #ifndef STBI_NO_PIC ; 612 : if (stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); 0044c 48 8b cf mov rcx, rdi ; 5907 : return 1; 0044f 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 00456 49 89 06 mov QWORD PTR [r14], rax ; 608 : #else ; 609 : STBI_NOTUSED(bpc); ; 610 : #endif ; 611 : #ifndef STBI_NO_PIC ; 612 : if (stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); 00459 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 0045d e8 00 00 00 00 call stbi__pic_load 00462 e9 47 03 00 00 jmp $LN1@stbi__load $LN156@stbi__load: ; 438 : return STBI_MALLOC(size); 00467 48 8b 97 d0 00 00 00 mov rdx, QWORD PTR [rdi+208] 0046e 49 8b ce mov rcx, r14 00471 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 00478 48 8b de mov rbx, rsi 0047b 48 89 13 mov QWORD PTR [rbx], rdx 0047e 48 89 01 mov QWORD PTR [rcx], rax 00481 b9 88 48 00 00 mov ecx, 18568 ; 00004888H 00486 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 0048c 4c 8b e8 mov r13, rax ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); 0048f 48 85 c0 test rax, rax 00492 75 3f jne SHORT $LN98@stbi__load ; 431 : stbi__g_failure_reason = str; 00494 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0049d 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 004a3 41 bd 00 00 00 00 mov r13d, OFFSET FLAT:stbi__g_failure_reason 004a9 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 004ad 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 004b4 49 89 44 15 00 mov QWORD PTR [r13+rdx], rax $LN7@stbi__load: ; 1077 : if (s->img_buffer < s->img_buffer_end) 004b9 48 8b 06 mov rax, QWORD PTR [rsi] 004bc 49 3b 06 cmp rax, QWORD PTR [r14] 004bf 0f 83 b2 01 00 00 jae $LN132@stbi__load ; 1078 : return *s->img_buffer++; 004c5 0f b6 18 movzx ebx, BYTE PTR [rax] 004c8 48 ff c0 inc rax 004cb 48 89 06 mov QWORD PTR [rsi], rax 004ce e9 c2 01 00 00 jmp $LN131@stbi__load $LN98@stbi__load: ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); 004d3 48 8d 48 08 lea rcx, QWORD PTR [rax+8] 004d7 33 d2 xor edx, edx 004d9 41 b8 68 48 00 00 mov r8d, 18536 ; 00004868H 004df e8 00 00 00 00 call memset ; 187 : __cpuid(info, 1); 004e4 33 c9 xor ecx, ecx ; 3539 : j->s = s; 004e6 49 89 7d 00 mov QWORD PTR [r13], rdi ; 3305 : j->idct_block_kernel = stbi__idct_block; 004ea 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_block 004f1 49 89 85 70 48 00 00 mov QWORD PTR [r13+18544], rax ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; 004f8 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_row 004ff 49 89 85 78 48 00 00 mov QWORD PTR [r13+18552], rax ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; 00506 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2 0050d 49 89 85 80 48 00 00 mov QWORD PTR [r13+18560], rax ; 187 : __cpuid(info, 1); 00514 b8 01 00 00 00 mov eax, 1 00519 0f a2 cpuid 0051b 89 44 24 60 mov DWORD PTR info$11[rsp], eax ; 3310 : if (stbi__sse2_available()) { 0051f 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_simd ; 187 : __cpuid(info, 1); 00526 89 5c 24 64 mov DWORD PTR info$11[rsp+4], ebx ; 3310 : if (stbi__sse2_available()) { 0052a 48 8d 1d 00 00 00 00 lea rbx, OFFSET FLAT:stbi__resample_row_hv_2_simd 00531 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__YCbCr_to_RGB_simd 00538 0f ba e2 1a bt edx, 26 0053c 73 15 jae SHORT $LN105@stbi__load ; 3311 : j->idct_block_kernel = stbi__idct_simd; 0053e 49 89 85 70 48 00 00 mov QWORD PTR [r13+18544], rax ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; 00545 49 89 8d 78 48 00 00 mov QWORD PTR [r13+18552], rcx ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; 0054c 49 89 9d 80 48 00 00 mov QWORD PTR [r13+18560], rbx $LN105@stbi__load: ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); 00553 ba 01 00 00 00 mov edx, 1 00558 49 8b cd mov rcx, r13 0055b e8 00 00 00 00 call stbi__decode_jpeg_header ; 342 : s->img_buffer = s->img_buffer_original; 00560 48 8b 97 d0 00 00 00 mov rdx, QWORD PTR [rdi+208] ; 3543 : STBI_FREE(j); 00567 49 8b cd mov rcx, r13 ; 342 : s->img_buffer = s->img_buffer_original; 0056a 48 89 16 mov QWORD PTR [rsi], rdx ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); 0056d 8b d8 mov ebx, eax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0056f 48 8b 97 d8 00 00 00 mov rdx, QWORD PTR [rdi+216] 00576 49 89 16 mov QWORD PTR [r14], rdx ; 3543 : STBI_FREE(j); 00579 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 3544 : return r; 0057f 41 bd 00 00 00 00 mov r13d, OFFSET FLAT:stbi__g_failure_reason 00585 41 8b c5 mov eax, r13d 00588 48 89 44 24 60 mov QWORD PTR tv1050[rsp], rax ; 613 : #endif ; 614 : ; 615 : // then the formats that can end up attempting to load with just 1 or 2 ; 616 : // bytes matching expectations; these are prone to false positives, so ; 617 : // try them later ; 618 : #ifndef STBI_NO_JPEG ; 619 : if (stbi__jpeg_test(s)) return stbi__jpeg_load(s, x, y, comp, req_comp, ri); 0058d 85 db test ebx, ebx 0058f 0f 84 24 ff ff ff je $LN7@stbi__load ; 438 : return STBI_MALLOC(size); 00595 b9 88 48 00 00 mov ecx, 18568 ; 00004888H 0059a ff 15 00 00 00 00 call QWORD PTR __imp_malloc 005a0 48 8b f0 mov rsi, rax ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); 005a3 48 85 c0 test rax, rax 005a6 75 2b jne SHORT $LN114@stbi__load ; 431 : stbi__g_failure_reason = str; 005a8 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 005ae 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 005b7 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 005bb 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 005c2 48 8b 4c 24 60 mov rcx, QWORD PTR tv1050[rsp] 005c7 48 89 04 11 mov QWORD PTR [rcx+rdx], rax ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); 005cb 49 8b c4 mov rax, r12 005ce e9 db 01 00 00 jmp $LN1@stbi__load $LN114@stbi__load: ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); 005d3 48 8d 48 08 lea rcx, QWORD PTR [rax+8] 005d7 33 d2 xor edx, edx 005d9 41 b8 68 48 00 00 mov r8d, 18536 ; 00004868H 005df e8 00 00 00 00 call memset ; 3305 : j->idct_block_kernel = stbi__idct_block; 005e4 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__idct_block ; 3526 : j->s = s; 005eb 48 89 3e mov QWORD PTR [rsi], rdi ; 3305 : j->idct_block_kernel = stbi__idct_block; 005ee 48 89 8e 70 48 00 00 mov QWORD PTR [rsi+18544], rcx ; 187 : __cpuid(info, 1); 005f5 b8 01 00 00 00 mov eax, 1 ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; 005fa 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__YCbCr_to_RGB_row 00601 48 89 8e 78 48 00 00 mov QWORD PTR [rsi+18552], rcx ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; 00608 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__resample_row_hv_2 0060f 48 89 8e 80 48 00 00 mov QWORD PTR [rsi+18560], rcx ; 187 : __cpuid(info, 1); 00616 33 c9 xor ecx, ecx 00618 0f a2 cpuid ; 3310 : if (stbi__sse2_available()) { 0061a 0f ba e2 1a bt edx, 26 0061e 73 2a jae SHORT $LN121@stbi__load ; 3311 : j->idct_block_kernel = stbi__idct_simd; 00620 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_simd 00627 48 89 86 70 48 00 00 mov QWORD PTR [rsi+18544], rax ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; 0062e 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_simd 00635 48 89 86 78 48 00 00 mov QWORD PTR [rsi+18552], rax ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; 0063c 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2_simd 00643 48 89 86 80 48 00 00 mov QWORD PTR [rsi+18560], rax $LN121@stbi__load: ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); 0064a 4c 8b 4c 24 58 mov r9, QWORD PTR comp$GSCopy$1$[rsp] 0064f 4d 8b c7 mov r8, r15 00652 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 00657 48 8b ce mov rcx, rsi 0065a 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 0065e e8 00 00 00 00 call load_jpeg_image ; 3529 : STBI_FREE(j); 00663 48 8b ce mov rcx, rsi 00666 4c 8b e0 mov r12, rax 00669 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 613 : #endif ; 614 : ; 615 : // then the formats that can end up attempting to load with just 1 or 2 ; 616 : // bytes matching expectations; these are prone to false positives, so ; 617 : // try them later ; 618 : #ifndef STBI_NO_JPEG ; 619 : if (stbi__jpeg_test(s)) return stbi__jpeg_load(s, x, y, comp, req_comp, ri); 0066f 49 8b c4 mov rax, r12 00672 e9 37 01 00 00 jmp $LN1@stbi__load $LN132@stbi__load: ; 1079 : if (s->read_from_callbacks) { 00677 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 0067b 74 16 je SHORT $LN133@stbi__load ; 1080 : stbi__refill_buffer(s); 0067d 48 8b cf mov rcx, rdi 00680 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00685 48 8b 06 mov rax, QWORD PTR [rsi] 00688 0f b6 18 movzx ebx, BYTE PTR [rax] 0068b 48 ff c0 inc rax 0068e 48 89 06 mov QWORD PTR [rsi], rax 00691 eb 02 jmp SHORT $LN131@stbi__load $LN133@stbi__load: ; 1082 : } ; 1083 : return 0; 00693 32 db xor bl, bl $LN131@stbi__load: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00695 49 3b 06 cmp rax, QWORD PTR [r14] 00698 73 0b jae SHORT $LN136@stbi__load ; 1078 : return *s->img_buffer++; 0069a 0f b6 08 movzx ecx, BYTE PTR [rax] 0069d 48 ff c0 inc rax 006a0 48 89 06 mov QWORD PTR [rsi], rax 006a3 eb 1e jmp SHORT $LN135@stbi__load $LN136@stbi__load: ; 1079 : if (s->read_from_callbacks) { 006a5 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 006a9 74 16 je SHORT $LN137@stbi__load ; 1080 : stbi__refill_buffer(s); 006ab 48 8b cf mov rcx, rdi 006ae e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 006b3 48 8b 06 mov rax, QWORD PTR [rsi] 006b6 0f b6 08 movzx ecx, BYTE PTR [rax] 006b9 48 ff c0 inc rax 006bc 48 89 06 mov QWORD PTR [rsi], rax 006bf eb 02 jmp SHORT $LN135@stbi__load $LN137@stbi__load: ; 1082 : } ; 1083 : return 0; 006c1 32 c9 xor cl, cl $LN135@stbi__load: ; 7067 : if (p != 'P' || (t != '5' && t != '6')) { 006c3 80 fb 50 cmp bl, 80 ; 00000050H 006c6 75 30 jne SHORT $LN129@stbi__load 006c8 80 e9 35 sub cl, 53 ; 00000035H 006cb 80 f9 01 cmp cl, 1 006ce 77 28 ja SHORT $LN129@stbi__load ; 620 : #endif ; 621 : #ifndef STBI_NO_PNM ; 622 : if (stbi__pnm_test(s)) return stbi__pnm_load(s, x, y, comp, req_comp, ri); 006d0 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 006d5 4d 8b c7 mov r8, r15 006d8 4c 8b 4c 24 58 mov r9, QWORD PTR comp$GSCopy$1$[rsp] 006dd 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 006e2 48 89 4c 24 28 mov QWORD PTR [rsp+40], rcx 006e7 48 8b cf mov rcx, rdi 006ea 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 006ee e8 00 00 00 00 call stbi__pnm_load 006f3 e9 b6 00 00 00 jmp $LN1@stbi__load $LN129@stbi__load: ; 342 : s->img_buffer = s->img_buffer_original; 006f8 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] ; 623 : #endif ; 624 : ; 625 : #ifndef STBI_NO_HDR ; 626 : if (stbi__hdr_test(s)) { 006ff 48 8b cf mov rcx, rdi ; 342 : s->img_buffer = s->img_buffer_original; 00702 48 89 06 mov QWORD PTR [rsi], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00705 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 0070c 49 89 06 mov QWORD PTR [r14], rax ; 623 : #endif ; 624 : ; 625 : #ifndef STBI_NO_HDR ; 626 : if (stbi__hdr_test(s)) { 0070f e8 00 00 00 00 call stbi__hdr_test 00714 85 c0 test eax, eax 00716 74 42 je SHORT $LN9@stbi__load ; 627 : float* hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); 00718 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 0071d 4d 8b c7 mov r8, r15 00720 48 8b 5c 24 58 mov rbx, QWORD PTR comp$GSCopy$1$[rsp] 00725 4c 8b 74 24 40 mov r14, QWORD PTR x$GSCopy$1$[rsp] 0072a 4c 8b cb mov r9, rbx 0072d 48 89 4c 24 28 mov QWORD PTR [rsp+40], rcx 00732 49 8b d6 mov rdx, r14 00735 48 8b cf mov rcx, rdi 00738 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 0073c e8 00 00 00 00 call stbi__hdr_load ; 628 : return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); 00741 85 ed test ebp, ebp 00743 75 02 jne SHORT $LN13@stbi__load 00745 8b 2b mov ebp, DWORD PTR [rbx] $LN13@stbi__load: 00747 45 8b 07 mov r8d, DWORD PTR [r15] 0074a 44 8b cd mov r9d, ebp 0074d 41 8b 16 mov edx, DWORD PTR [r14] 00750 48 8b c8 mov rcx, rax 00753 e8 00 00 00 00 call stbi__hdr_to_ldr 00758 eb 54 jmp SHORT $LN1@stbi__load $LN9@stbi__load: ; 629 : } ; 630 : #endif ; 631 : ; 632 : #ifndef STBI_NO_TGA ; 633 : // test tga last because it's a crappy test! ; 634 : if (stbi__tga_test(s)) 0075a 48 8b cf mov rcx, rdi 0075d e8 00 00 00 00 call stbi__tga_test 00762 85 c0 test eax, eax 00764 74 25 je SHORT $LN10@stbi__load ; 635 : return stbi__tga_load(s, x, y, comp, req_comp, ri); 00766 48 8b 4c 24 50 mov rcx, QWORD PTR ri$GSCopy$1$[rsp] 0076b 4d 8b c7 mov r8, r15 0076e 4c 8b 4c 24 58 mov r9, QWORD PTR comp$GSCopy$1$[rsp] 00773 48 8b 54 24 40 mov rdx, QWORD PTR x$GSCopy$1$[rsp] 00778 48 89 4c 24 28 mov QWORD PTR [rsp+40], rcx 0077d 48 8b cf mov rcx, rdi 00780 89 6c 24 20 mov DWORD PTR [rsp+32], ebp 00784 e8 00 00 00 00 call stbi__tga_load 00789 eb 23 jmp SHORT $LN1@stbi__load $LN10@stbi__load: ; 431 : stbi__g_failure_reason = str; 0078b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00794 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 0079a 41 8b dd mov ebx, r13d 0079d 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 007a1 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0BD@CBEDEJPH@unknown?5image?5type@ 007a8 48 89 04 13 mov QWORD PTR [rbx+rdx], rax ; 636 : #endif ; 637 : ; 638 : return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); 007ac 33 c0 xor eax, eax $LN1@stbi__load: ; 639 : } 007ae 48 8b 8c 24 98 00 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 007b6 48 33 cc xor rcx, rsp 007b9 e8 00 00 00 00 call __security_check_cookie 007be 48 81 c4 a8 00 00 00 add rsp, 168 ; 000000a8H 007c5 41 5f pop r15 007c7 41 5e pop r14 007c9 41 5d pop r13 007cb 41 5c pop r12 007cd 5f pop rdi 007ce 5e pop rsi 007cf 5d pop rbp 007d0 5b pop rbx 007d1 c3 ret 0 stbi__load_main ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__convert_16_to_8 _TEXT SEGMENT orig$ = 48 w$ = 56 h$ = 64 channels$ = 72 stbi__convert_16_to_8 PROC ; COMDAT ; 642 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 57 push rdi 00010 48 83 ec 20 sub rsp, 32 ; 00000020H 00014 8b da mov ebx, edx 00016 48 8b f1 mov rsi, rcx ; 643 : int i; ; 644 : int img_len = w * h * channels; 00019 41 0f af d8 imul ebx, r8d 0001d 41 0f af d9 imul ebx, r9d ; 645 : stbi_uc* reduced; ; 646 : ; 647 : reduced = (stbi_uc*)stbi__malloc(img_len); 00021 48 63 eb movsxd rbp, ebx ; 438 : return STBI_MALLOC(size); 00024 48 8b cd mov rcx, rbp 00027 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 0002d 48 8b f8 mov rdi, rax ; 648 : if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); 00030 48 85 c0 test rax, rax 00033 75 2a jne SHORT $LN5@stbi__conv ; 431 : stbi__g_failure_reason = str; 00035 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0003e 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00044 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 00049 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 0004d 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00054 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 648 : if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); 00058 33 c0 xor eax, eax 0005a e9 4d 01 00 00 jmp $LN1@stbi__conv $LN5@stbi__conv: ; 649 : ; 650 : for (i = 0; i < img_len; ++i) 0005f 45 33 c0 xor r8d, r8d 00062 41 8b d0 mov edx, r8d 00065 85 db test ebx, ebx 00067 0f 8e 19 01 00 00 jle $LN14@stbi__conv 0006d 83 fb 04 cmp ebx, 4 00070 0f 82 10 01 00 00 jb $LN14@stbi__conv 00076 8d 43 ff lea eax, DWORD PTR [rbx-1] 00079 48 63 c8 movsxd rcx, eax 0007c 48 8d 04 4e lea rax, QWORD PTR [rsi+rcx*2] 00080 4c 8d 0c 39 lea r9, QWORD PTR [rcx+rdi] 00084 48 3b f8 cmp rdi, rax 00087 77 09 ja SHORT $LN17@stbi__conv 00089 4c 3b ce cmp r9, rsi 0008c 0f 83 f4 00 00 00 jae $LN14@stbi__conv $LN17@stbi__conv: 00092 83 fb 20 cmp ebx, 32 ; 00000020H 00095 0f 82 ac 00 00 00 jb $LN16@stbi__conv ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 0009b 8b cb mov ecx, ebx 0009d 81 e1 1f 00 00 80 and ecx, -2147483617 ; ffffffff8000001fH 000a3 7d 07 jge SHORT $LN28@stbi__conv 000a5 ff c9 dec ecx 000a7 83 c9 e0 or ecx, -32 ; ffffffffffffffe0H 000aa ff c1 inc ecx $LN28@stbi__conv: 000ac 8b c3 mov eax, ebx 000ae 2b c1 sub eax, ecx ; 649 : ; 650 : for (i = 0; i < img_len; ++i) 000b0 48 63 c8 movsxd rcx, eax ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 000b3 48 8d 46 20 lea rax, QWORD PTR [rsi+32] 000b7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL4@stbi__conv: 000c0 f3 0f 6f 40 e0 movdqu xmm0, XMMWORD PTR [rax-32] 000c5 83 c2 20 add edx, 32 ; 00000020H 000c8 f3 0f 6f 48 f0 movdqu xmm1, XMMWORD PTR [rax-16] 000cd 48 8d 40 40 lea rax, QWORD PTR [rax+64] 000d1 66 0f 71 d0 08 psrlw xmm0, 8 000d6 0f 54 05 00 00 00 00 andps xmm0, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 000dd 66 0f 71 d1 08 psrlw xmm1, 8 000e2 0f 54 0d 00 00 00 00 andps xmm1, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 000e9 66 0f 67 c0 packuswb xmm0, xmm0 000ed 66 42 0f d6 04 07 movq QWORD PTR [rdi+r8], xmm0 000f3 f3 0f 6f 40 c0 movdqu xmm0, XMMWORD PTR [rax-64] 000f8 66 0f 67 c9 packuswb xmm1, xmm1 000fc 66 42 0f d6 4c 07 08 movq QWORD PTR [rdi+r8+8], xmm1 00103 f3 0f 6f 48 d0 movdqu xmm1, XMMWORD PTR [rax-48] 00108 66 0f 71 d0 08 psrlw xmm0, 8 0010d 0f 54 05 00 00 00 00 andps xmm0, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 00114 66 0f 71 d1 08 psrlw xmm1, 8 00119 0f 54 0d 00 00 00 00 andps xmm1, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 00120 66 0f 67 c0 packuswb xmm0, xmm0 00124 66 42 0f d6 44 07 10 movq QWORD PTR [rdi+r8+16], xmm0 0012b 66 0f 67 c9 packuswb xmm1, xmm1 0012f 66 42 0f d6 4c 07 18 movq QWORD PTR [rdi+r8+24], xmm1 00136 49 83 c0 20 add r8, 32 ; 00000020H 0013a 4c 3b c1 cmp r8, rcx 0013d 7c 81 jl SHORT $LL4@stbi__conv ; 649 : ; 650 : for (i = 0; i < img_len; ++i) 0013f 8b c3 mov eax, ebx 00141 24 1f and al, 31 00143 3c 04 cmp al, 4 00145 72 3f jb SHORT $LN14@stbi__conv $LN16@stbi__conv: ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 00147 8b c3 mov eax, ebx 00149 25 03 00 00 80 and eax, -2147483645 ; ffffffff80000003H 0014e 7d 07 jge SHORT $LN27@stbi__conv 00150 ff c8 dec eax 00152 83 c8 fc or eax, -4 00155 ff c0 inc eax $LN27@stbi__conv: 00157 2b d8 sub ebx, eax ; 649 : ; 650 : for (i = 0; i < img_len; ++i) 00159 48 63 c2 movsxd rax, edx 0015c 48 63 cb movsxd rcx, ebx 0015f 90 npad 1 $LL15@stbi__conv: ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 00160 f3 0f 7e 04 46 movq xmm0, QWORD PTR [rsi+rax*2] 00165 83 c2 04 add edx, 4 00168 66 0f 71 d0 08 psrlw xmm0, 8 0016d 0f 54 05 00 00 00 00 andps xmm0, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 00174 66 0f 67 c0 packuswb xmm0, xmm0 00178 66 0f 7e 04 38 movd DWORD PTR [rax+rdi], xmm0 0017d 48 83 c0 04 add rax, 4 00181 48 3b c1 cmp rax, rcx 00184 7c da jl SHORT $LL15@stbi__conv $LN14@stbi__conv: ; 649 : ; 650 : for (i = 0; i < img_len; ++i) 00186 48 63 c2 movsxd rax, edx 00189 48 3b c5 cmp rax, rbp 0018c 7d 12 jge SHORT $LN3@stbi__conv 0018e 66 90 npad 2 $LL13@stbi__conv: ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling 00190 0f b6 4c 46 01 movzx ecx, BYTE PTR [rsi+rax*2+1] 00195 88 0c 38 mov BYTE PTR [rax+rdi], cl 00198 48 ff c0 inc rax 0019b 48 3b c5 cmp rax, rbp 0019e 7c f0 jl SHORT $LL13@stbi__conv $LN3@stbi__conv: ; 652 : ; 653 : STBI_FREE(orig); 001a0 48 8b ce mov rcx, rsi 001a3 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 654 : return reduced; 001a9 48 8b c7 mov rax, rdi $LN1@stbi__conv: ; 655 : } 001ac 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 001b1 48 8b 6c 24 38 mov rbp, QWORD PTR [rsp+56] 001b6 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 001bb 48 83 c4 20 add rsp, 32 ; 00000020H 001bf 5f pop rdi 001c0 c3 ret 0 stbi__convert_16_to_8 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__vertical_flip _TEXT SEGMENT temp$ = 32 __$ArrayPad$ = 2080 image$ = 2176 w$ = 2184 h$ = 2192 bytes_per_pixel$ = 2200 stbi__vertical_flip PROC ; COMDAT ; 674 : { 00000 4c 8b dc mov r11, rsp 00003 41 54 push r12 00005 41 57 push r15 00007 48 81 ec 68 08 00 00 sub rsp, 2152 ; 00000868H 0000e 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00015 48 33 c4 xor rax, rsp 00018 48 89 84 24 20 08 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00020 4c 8b e1 mov r12, rcx ; 675 : int row; ; 676 : size_t bytes_per_row = (size_t)w * bytes_per_pixel; 00023 4d 63 f9 movsxd r15, r9d ; 677 : stbi_uc temp[2048]; ; 678 : stbi_uc* bytes = (stbi_uc*)image; ; 679 : ; 680 : for (row = 0; row < (h >> 1); row++) { 00026 41 8b c8 mov ecx, r8d 00029 48 63 c2 movsxd rax, edx 0002c d1 f9 sar ecx, 1 0002e 4c 0f af f8 imul r15, rax 00032 85 c9 test ecx, ecx 00034 0f 8e c7 00 00 00 jle $LN3@stbi__vert 0003a 49 89 5b e8 mov QWORD PTR [r11-24], rbx 0003e 41 8d 40 ff lea eax, DWORD PTR [r8-1] 00042 49 89 6b e0 mov QWORD PTR [r11-32], rbp 00046 49 89 73 d8 mov QWORD PTR [r11-40], rsi 0004a 49 89 7b d0 mov QWORD PTR [r11-48], rdi 0004e 4d 89 6b c8 mov QWORD PTR [r11-56], r13 00052 48 63 d8 movsxd rbx, eax 00055 49 0f af df imul rbx, r15 00059 4d 89 73 c0 mov QWORD PTR [r11-64], r14 0005d 49 03 dc add rbx, r12 00060 44 8b e9 mov r13d, ecx 00063 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL4@stbi__vert: ; 681 : stbi_uc* row0 = bytes + row * bytes_per_row; 00070 49 8b f4 mov rsi, r12 ; 682 : stbi_uc* row1 = bytes + (h - row - 1) * bytes_per_row; 00073 48 8b eb mov rbp, rbx ; 683 : // swap row0 with row1 ; 684 : size_t bytes_left = bytes_per_row; 00076 4d 8b f7 mov r14, r15 ; 685 : while (bytes_left) { 00079 4d 85 ff test r15, r15 0007c 74 47 je SHORT $LN2@stbi__vert 0007e 66 90 npad 2 $LL5@stbi__vert: ; 686 : size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); 00080 bf 00 08 00 00 mov edi, 2048 ; 00000800H ; 687 : memcpy(temp, row0, bytes_copy); 00085 48 8d 4c 24 20 lea rcx, QWORD PTR temp$[rsp] 0008a 4c 3b f7 cmp r14, rdi 0008d 48 8b d6 mov rdx, rsi 00090 49 0f 42 fe cmovb rdi, r14 00094 4c 8b c7 mov r8, rdi 00097 e8 00 00 00 00 call memcpy ; 688 : memcpy(row0, row1, bytes_copy); 0009c 4c 8b c7 mov r8, rdi 0009f 48 8b d5 mov rdx, rbp 000a2 48 8b ce mov rcx, rsi 000a5 e8 00 00 00 00 call memcpy ; 689 : memcpy(row1, temp, bytes_copy); 000aa 4c 8b c7 mov r8, rdi 000ad 48 8d 54 24 20 lea rdx, QWORD PTR temp$[rsp] 000b2 48 8b cd mov rcx, rbp 000b5 e8 00 00 00 00 call memcpy ; 690 : row0 += bytes_copy; 000ba 48 03 f7 add rsi, rdi ; 691 : row1 += bytes_copy; 000bd 48 03 ef add rbp, rdi ; 692 : bytes_left -= bytes_copy; 000c0 4c 2b f7 sub r14, rdi 000c3 75 bb jne SHORT $LL5@stbi__vert $LN2@stbi__vert: ; 677 : stbi_uc temp[2048]; ; 678 : stbi_uc* bytes = (stbi_uc*)image; ; 679 : ; 680 : for (row = 0; row < (h >> 1); row++) { 000c5 4d 03 e7 add r12, r15 000c8 49 2b df sub rbx, r15 000cb 49 83 ed 01 sub r13, 1 000cf 75 9f jne SHORT $LL4@stbi__vert 000d1 4c 8b b4 24 38 08 00 00 mov r14, QWORD PTR [rsp+2104] 000d9 4c 8b ac 24 40 08 00 00 mov r13, QWORD PTR [rsp+2112] 000e1 48 8b bc 24 48 08 00 00 mov rdi, QWORD PTR [rsp+2120] 000e9 48 8b b4 24 50 08 00 00 mov rsi, QWORD PTR [rsp+2128] 000f1 48 8b ac 24 58 08 00 00 mov rbp, QWORD PTR [rsp+2136] 000f9 48 8b 9c 24 60 08 00 00 mov rbx, QWORD PTR [rsp+2144] $LN3@stbi__vert: ; 693 : } ; 694 : } ; 695 : } 00101 48 8b 8c 24 20 08 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00109 48 33 cc xor rcx, rsp 0010c e8 00 00 00 00 call __security_check_cookie 00111 48 81 c4 68 08 00 00 add rsp, 2152 ; 00000868H 00118 41 5f pop r15 0011a 41 5c pop r12 0011c c3 ret 0 stbi__vertical_flip ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__load_and_postprocess_8bit _TEXT SEGMENT ri$ = 64 __$ArrayPad$ = 80 s$ = 144 x$ = 152 y$ = 160 comp$ = 168 req_comp$ = 176 stbi__load_and_postprocess_8bit PROC ; COMDAT ; 712 : { 00000 40 53 push rbx 00002 56 push rsi 00003 57 push rdi 00004 41 56 push r14 00006 41 57 push r15 00008 48 83 ec 60 sub rsp, 96 ; 00000060H 0000c 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00013 48 33 c4 xor rax, rsp 00016 48 89 44 24 50 mov QWORD PTR __$ArrayPad$[rsp], rax 0001b 8b 9c 24 b0 00 00 00 mov ebx, DWORD PTR req_comp$[rsp] ; 713 : stbi__result_info ri; ; 714 : void* result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); 00022 48 8d 44 24 40 lea rax, QWORD PTR ri$[rsp] 00027 48 89 44 24 28 mov QWORD PTR [rsp+40], rax 0002c 49 8b f1 mov rsi, r9 0002f 89 5c 24 20 mov DWORD PTR [rsp+32], ebx 00033 4d 8b f8 mov r15, r8 00036 4c 8b f2 mov r14, rdx 00039 e8 00 00 00 00 call stbi__load_main 0003e 48 8b f8 mov rdi, rax ; 715 : ; 716 : if (result == NULL) 00041 48 85 c0 test rax, rax 00044 74 78 je SHORT $LN1@stbi__load $LN2@stbi__load: ; 717 : return NULL; ; 718 : ; 719 : // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. ; 720 : STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); ; 721 : ; 722 : if (ri.bits_per_channel != 8) { 00046 83 7c 24 40 08 cmp DWORD PTR ri$[rsp], 8 0004b 74 25 je SHORT $LN3@stbi__load ; 723 : result = stbi__convert_16_to_8((stbi__uint16*)result, *x, *y, req_comp == 0 ? *comp : req_comp); 0004d 85 db test ebx, ebx 0004f 75 05 jne SHORT $LN6@stbi__load 00051 44 8b 0e mov r9d, DWORD PTR [rsi] 00054 eb 03 jmp SHORT $LN7@stbi__load $LN6@stbi__load: 00056 44 8b cb mov r9d, ebx $LN7@stbi__load: 00059 45 8b 07 mov r8d, DWORD PTR [r15] 0005c 48 8b c8 mov rcx, rax 0005f 41 8b 16 mov edx, DWORD PTR [r14] 00062 e8 00 00 00 00 call stbi__convert_16_to_8 00067 48 8b f8 mov rdi, rax ; 724 : ri.bits_per_channel = 8; 0006a c7 44 24 40 08 00 00 00 mov DWORD PTR ri$[rsp], 8 $LN3@stbi__load: ; 725 : } ; 726 : ; 727 : // @TODO: move stbi__convert_format to here ; 728 : ; 729 : if (stbi__vertically_flip_on_load) { 00072 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00078 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00081 48 8b 04 c8 mov rax, QWORD PTR [rax+rcx*8] 00085 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__vertically_flip_on_load_set 0008a 83 3c 01 00 cmp DWORD PTR [rcx+rax], 0 0008e 74 0a je SHORT $LN8@stbi__load 00090 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__vertically_flip_on_load_local 00095 8b 04 01 mov eax, DWORD PTR [rcx+rax] 00098 eb 06 jmp SHORT $LN9@stbi__load $LN8@stbi__load: 0009a 8b 05 00 00 00 00 mov eax, DWORD PTR stbi__vertically_flip_on_load_global $LN9@stbi__load: 000a0 85 c0 test eax, eax 000a2 74 17 je SHORT $LN4@stbi__load ; 730 : int channels = req_comp ? req_comp : *comp; 000a4 85 db test ebx, ebx 000a6 75 02 jne SHORT $LN11@stbi__load 000a8 8b 1e mov ebx, DWORD PTR [rsi] $LN11@stbi__load: ; 731 : stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); 000aa 45 8b 07 mov r8d, DWORD PTR [r15] 000ad 44 8b cb mov r9d, ebx 000b0 41 8b 16 mov edx, DWORD PTR [r14] 000b3 48 8b cf mov rcx, rdi 000b6 e8 00 00 00 00 call stbi__vertical_flip $LN4@stbi__load: ; 732 : } ; 733 : ; 734 : return (unsigned char*)result; 000bb 48 8b c7 mov rax, rdi $LN1@stbi__load: ; 735 : } 000be 48 8b 4c 24 50 mov rcx, QWORD PTR __$ArrayPad$[rsp] 000c3 48 33 cc xor rcx, rsp 000c6 e8 00 00 00 00 call __security_check_cookie 000cb 48 83 c4 60 add rsp, 96 ; 00000060H 000cf 41 5f pop r15 000d1 41 5e pop r14 000d3 5f pop rdi 000d4 5e pop rsi 000d5 5b pop rbx 000d6 c3 ret 0 stbi__load_and_postprocess_8bit ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__fopen _TEXT SEGMENT f$ = 32 __$ArrayPad$ = 40 filename$ = 64 mode$dead$ = 72 stbi__fopen PROC ; COMDAT ; 789 : { 00000 48 83 ec 38 sub rsp, 56 ; 00000038H 00004 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0000b 48 33 c4 xor rax, rsp 0000e 48 89 44 24 28 mov QWORD PTR __$ArrayPad$[rsp], rax ; 790 : FILE* f; ; 791 : #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) ; 792 : wchar_t wMode[64]; ; 793 : wchar_t wFilename[1024]; ; 794 : if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename) / sizeof(*wFilename))) ; 795 : return 0; ; 796 : ; 797 : if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode) / sizeof(*wMode))) ; 798 : return 0; ; 799 : ; 800 : #if defined(_MSC_VER) && _MSC_VER >= 1400 ; 801 : if (0 != _wfopen_s(&f, wFilename, wMode)) ; 802 : f = 0; ; 803 : #else ; 804 : f = _wfopen(wFilename, wMode); ; 805 : #endif ; 806 : ; 807 : #elif defined(_MSC_VER) && _MSC_VER >= 1400 ; 808 : if (0 != fopen_s(&f, filename, mode)) 00013 48 8b d1 mov rdx, rcx 00016 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:??_C@_02JDPG@rb@ 0001d 48 8d 4c 24 20 lea rcx, QWORD PTR f$[rsp] 00022 ff 15 00 00 00 00 call QWORD PTR __imp_fopen_s 00028 85 c0 test eax, eax 0002a 74 14 je SHORT $LN4@stbi__fope ; 809 : f = 0; ; 810 : #else ; 811 : f = fopen(filename, mode); ; 812 : #endif ; 813 : return f; 0002c 33 c0 xor eax, eax ; 814 : } 0002e 48 8b 4c 24 28 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00033 48 33 cc xor rcx, rsp 00036 e8 00 00 00 00 call __security_check_cookie 0003b 48 83 c4 38 add rsp, 56 ; 00000038H 0003f c3 ret 0 $LN4@stbi__fope: ; 809 : f = 0; ; 810 : #else ; 811 : f = fopen(filename, mode); ; 812 : #endif ; 813 : return f; 00040 48 8b 44 24 20 mov rax, QWORD PTR f$[rsp] ; 814 : } 00045 48 8b 4c 24 28 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0004a 48 33 cc xor rcx, rsp 0004d e8 00 00 00 00 call __security_check_cookie 00052 48 83 c4 38 add rsp, 56 ; 00000038H 00056 c3 ret 0 stbi__fopen ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi_load _TEXT SEGMENT f$1 = 48 __$ArrayPad$ = 56 filename$ = 112 x$ = 120 y$ = 128 comp$ = 136 req_comp$ = 144 stbi_load PROC ; COMDAT ; 817 : { $LN13: 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 56 push r14 00007 48 83 ec 40 sub rsp, 64 ; 00000040H 0000b 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00012 48 33 c4 xor rax, rsp 00015 48 89 44 24 38 mov QWORD PTR __$ArrayPad$[rsp], rax 0001a 44 8b b4 24 90 00 00 00 mov r14d, DWORD PTR req_comp$[rsp] 00022 48 8b da mov rbx, rdx ; 808 : if (0 != fopen_s(&f, filename, mode)) 00025 48 8b d1 mov rdx, rcx ; 817 : { 00028 49 8b f0 mov rsi, r8 ; 808 : if (0 != fopen_s(&f, filename, mode)) 0002b 48 8d 4c 24 30 lea rcx, QWORD PTR f$1[rsp] ; 817 : { 00030 49 8b e9 mov rbp, r9 ; 808 : if (0 != fopen_s(&f, filename, mode)) 00033 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:??_C@_02JDPG@rb@ 0003a ff 15 00 00 00 00 call QWORD PTR __imp_fopen_s 00040 85 c0 test eax, eax 00042 74 09 je SHORT $LN9@stbi_load ; 809 : f = 0; 00044 33 ff xor edi, edi 00046 48 89 7c 24 30 mov QWORD PTR f$1[rsp], rdi 0004b eb 05 jmp SHORT $LN5@stbi_load $LN9@stbi_load: ; 432 : return 0; ; 433 : } ; 434 : #endif ; 435 : ; 436 : static void* stbi__malloc(size_t size) ; 437 : { ; 438 : return STBI_MALLOC(size); ; 439 : } ; 440 : ; 441 : // stb_image uses ints pervasively, including for offset calculations. ; 442 : // therefore the largest decoded image size we can support with the ; 443 : // current code, even on 64-bit targets, is INT_MAX. this is not a ; 444 : // significant limitation for the intended use case. ; 445 : // ; 446 : // we do, however, need to make sure our size calculations don't ; 447 : // overflow. hence a few helper functions for size calculations that ; 448 : // multiply integers together, making sure that they're non-negative ; 449 : // and no overflow occurs. ; 450 : ; 451 : // return 1 if the sum is valid, 0 on overflow. ; 452 : // negative terms are considered invalid. ; 453 : static int stbi__addsizes_valid(int a, int b) ; 454 : { ; 455 : if (b < 0) return 0; ; 456 : // now 0 <= b <= INT_MAX, hence also ; 457 : // 0 <= INT_MAX - b <= INTMAX. ; 458 : // And "a + b <= INT_MAX" (which might overflow) is the ; 459 : // same as a <= INT_MAX - b (no overflow) ; 460 : return a <= INT_MAX - b; ; 461 : } ; 462 : ; 463 : // returns 1 if the product is valid, 0 on overflow. ; 464 : // negative factors are considered invalid. ; 465 : static int stbi__mul2sizes_valid(int a, int b) ; 466 : { ; 467 : if (a < 0 || b < 0) return 0; ; 468 : if (b == 0) return 1; // mul-by-0 is always safe ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; ; 471 : } ; 472 : ; 473 : #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) ; 474 : // returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow ; 475 : static int stbi__mad2sizes_valid(int a, int b, int add) ; 476 : { ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); ; 478 : } ; 479 : #endif ; 480 : ; 481 : // returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow ; 482 : static int stbi__mad3sizes_valid(int a, int b, int c, int add) ; 483 : { ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && ; 485 : stbi__addsizes_valid(a * b * c, add); ; 486 : } ; 487 : ; 488 : // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow ; 489 : #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) ; 490 : static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) ; 491 : { ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && ; 493 : stbi__mul2sizes_valid(a * b * c, d) && stbi__addsizes_valid(a * b * c * d, add); ; 494 : } ; 495 : #endif ; 496 : ; 497 : #if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) ; 498 : // mallocs with size overflow checking ; 499 : static void* stbi__malloc_mad2(int a, int b, int add) ; 500 : { ; 501 : if (!stbi__mad2sizes_valid(a, b, add)) return NULL; ; 502 : return stbi__malloc(a * b + add); ; 503 : } ; 504 : #endif ; 505 : ; 506 : static void* stbi__malloc_mad3(int a, int b, int c, int add) ; 507 : { ; 508 : if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; ; 509 : return stbi__malloc(a * b * c + add); ; 510 : } ; 511 : ; 512 : #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) || !defined(STBI_NO_PNM) ; 513 : static void* stbi__malloc_mad4(int a, int b, int c, int d, int add) ; 514 : { ; 515 : if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; ; 516 : return stbi__malloc(a * b * c * d + add); ; 517 : } ; 518 : #endif ; 519 : ; 520 : // returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow. ; 521 : static int stbi__addints_valid(int a, int b) ; 522 : { ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow ; 524 : if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. ; 525 : return a <= INT_MAX - b; ; 526 : } ; 527 : ; 528 : // returns 1 if the product of two signed shorts is valid, 0 on overflow. ; 529 : static int stbi__mul2shorts_valid(short a, short b) ; 530 : { ; 531 : if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow ; 532 : if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid ; 533 : if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN ; 534 : return a >= SHRT_MIN / b; ; 535 : } ; 536 : ; 537 : // stbi__err - error ; 538 : // stbi__errpf - error returning pointer to float ; 539 : // stbi__errpuc - error returning pointer to unsigned char ; 540 : ; 541 : #ifdef STBI_NO_FAILURE_STRINGS ; 542 : #define stbi__err(x,y) 0 ; 543 : #elif defined(STBI_FAILURE_USERMSG) ; 544 : #define stbi__err(x,y) stbi__err(y) ; 545 : #else ; 546 : #define stbi__err(x,y) stbi__err(x) ; 547 : #endif ; 548 : ; 549 : #define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) ; 550 : #define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) ; 551 : ; 552 : STBIDEF void stbi_image_free(void* retval_from_stbi_load) ; 553 : { ; 554 : STBI_FREE(retval_from_stbi_load); ; 555 : } ; 556 : ; 557 : #ifndef STBI_NO_LINEAR ; 558 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp); ; 559 : #endif ; 560 : ; 561 : #ifndef STBI_NO_HDR ; 562 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp); ; 563 : #endif ; 564 : ; 565 : static int stbi__vertically_flip_on_load_global = 0; ; 566 : ; 567 : STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) ; 568 : { ; 569 : stbi__vertically_flip_on_load_global = flag_true_if_should_flip; ; 570 : } ; 571 : ; 572 : #ifndef STBI_THREAD_LOCAL ; 573 : #define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global ; 574 : #else ; 575 : static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; ; 576 : ; 577 : STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) ; 578 : { ; 579 : stbi__vertically_flip_on_load_local = flag_true_if_should_flip; ; 580 : stbi__vertically_flip_on_load_set = 1; ; 581 : } ; 582 : ; 583 : #define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ ; 584 : ? stbi__vertically_flip_on_load_local \ ; 585 : : stbi__vertically_flip_on_load_global) ; 586 : #endif // STBI_THREAD_LOCAL ; 587 : ; 588 : static void* stbi__load_main(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 589 : { ; 590 : memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields ; 591 : ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed ; 592 : ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order ; 593 : ri->num_channels = 0; ; 594 : ; 595 : // test the formats with a very explicit header first (at least a FOURCC ; 596 : // or distinctive magic number first) ; 597 : #ifndef STBI_NO_PNG ; 598 : if (stbi__png_test(s)) return stbi__png_load(s, x, y, comp, req_comp, ri); ; 599 : #endif ; 600 : #ifndef STBI_NO_BMP ; 601 : if (stbi__bmp_test(s)) return stbi__bmp_load(s, x, y, comp, req_comp, ri); ; 602 : #endif ; 603 : #ifndef STBI_NO_GIF ; 604 : if (stbi__gif_test(s)) return stbi__gif_load(s, x, y, comp, req_comp, ri); ; 605 : #endif ; 606 : #ifndef STBI_NO_PSD ; 607 : if (stbi__psd_test(s)) return stbi__psd_load(s, x, y, comp, req_comp, ri, bpc); ; 608 : #else ; 609 : STBI_NOTUSED(bpc); ; 610 : #endif ; 611 : #ifndef STBI_NO_PIC ; 612 : if (stbi__pic_test(s)) return stbi__pic_load(s, x, y, comp, req_comp, ri); ; 613 : #endif ; 614 : ; 615 : // then the formats that can end up attempting to load with just 1 or 2 ; 616 : // bytes matching expectations; these are prone to false positives, so ; 617 : // try them later ; 618 : #ifndef STBI_NO_JPEG ; 619 : if (stbi__jpeg_test(s)) return stbi__jpeg_load(s, x, y, comp, req_comp, ri); ; 620 : #endif ; 621 : #ifndef STBI_NO_PNM ; 622 : if (stbi__pnm_test(s)) return stbi__pnm_load(s, x, y, comp, req_comp, ri); ; 623 : #endif ; 624 : ; 625 : #ifndef STBI_NO_HDR ; 626 : if (stbi__hdr_test(s)) { ; 627 : float* hdr = stbi__hdr_load(s, x, y, comp, req_comp, ri); ; 628 : return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); ; 629 : } ; 630 : #endif ; 631 : ; 632 : #ifndef STBI_NO_TGA ; 633 : // test tga last because it's a crappy test! ; 634 : if (stbi__tga_test(s)) ; 635 : return stbi__tga_load(s, x, y, comp, req_comp, ri); ; 636 : #endif ; 637 : ; 638 : return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); ; 639 : } ; 640 : ; 641 : static stbi_uc* stbi__convert_16_to_8(stbi__uint16* orig, int w, int h, int channels) ; 642 : { ; 643 : int i; ; 644 : int img_len = w * h * channels; ; 645 : stbi_uc* reduced; ; 646 : ; 647 : reduced = (stbi_uc*)stbi__malloc(img_len); ; 648 : if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); ; 649 : ; 650 : for (i = 0; i < img_len; ++i) ; 651 : reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling ; 652 : ; 653 : STBI_FREE(orig); ; 654 : return reduced; ; 655 : } ; 656 : ; 657 : static stbi__uint16* stbi__convert_8_to_16(stbi_uc* orig, int w, int h, int channels) ; 658 : { ; 659 : int i; ; 660 : int img_len = w * h * channels; ; 661 : stbi__uint16* enlarged; ; 662 : ; 663 : enlarged = (stbi__uint16*)stbi__malloc(img_len * 2); ; 664 : if (enlarged == NULL) return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 665 : ; 666 : for (i = 0; i < img_len; ++i) ; 667 : enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff ; 668 : ; 669 : STBI_FREE(orig); ; 670 : return enlarged; ; 671 : } ; 672 : ; 673 : static void stbi__vertical_flip(void* image, int w, int h, int bytes_per_pixel) ; 674 : { ; 675 : int row; ; 676 : size_t bytes_per_row = (size_t)w * bytes_per_pixel; ; 677 : stbi_uc temp[2048]; ; 678 : stbi_uc* bytes = (stbi_uc*)image; ; 679 : ; 680 : for (row = 0; row < (h >> 1); row++) { ; 681 : stbi_uc* row0 = bytes + row * bytes_per_row; ; 682 : stbi_uc* row1 = bytes + (h - row - 1) * bytes_per_row; ; 683 : // swap row0 with row1 ; 684 : size_t bytes_left = bytes_per_row; ; 685 : while (bytes_left) { ; 686 : size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); ; 687 : memcpy(temp, row0, bytes_copy); ; 688 : memcpy(row0, row1, bytes_copy); ; 689 : memcpy(row1, temp, bytes_copy); ; 690 : row0 += bytes_copy; ; 691 : row1 += bytes_copy; ; 692 : bytes_left -= bytes_copy; ; 693 : } ; 694 : } ; 695 : } ; 696 : ; 697 : #ifndef STBI_NO_GIF ; 698 : static void stbi__vertical_flip_slices(void* image, int w, int h, int z, int bytes_per_pixel) ; 699 : { ; 700 : int slice; ; 701 : int slice_size = w * h * bytes_per_pixel; ; 702 : ; 703 : stbi_uc* bytes = (stbi_uc*)image; ; 704 : for (slice = 0; slice < z; ++slice) { ; 705 : stbi__vertical_flip(bytes, w, h, bytes_per_pixel); ; 706 : bytes += slice_size; ; 707 : } ; 708 : } ; 709 : #endif ; 710 : ; 711 : static unsigned char* stbi__load_and_postprocess_8bit(stbi__context* s, int* x, int* y, int* comp, int req_comp) ; 712 : { ; 713 : stbi__result_info ri; ; 714 : void* result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); ; 715 : ; 716 : if (result == NULL) ; 717 : return NULL; ; 718 : ; 719 : // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. ; 720 : STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); ; 721 : ; 722 : if (ri.bits_per_channel != 8) { ; 723 : result = stbi__convert_16_to_8((stbi__uint16*)result, *x, *y, req_comp == 0 ? *comp : req_comp); ; 724 : ri.bits_per_channel = 8; ; 725 : } ; 726 : ; 727 : // @TODO: move stbi__convert_format to here ; 728 : ; 729 : if (stbi__vertically_flip_on_load) { ; 730 : int channels = req_comp ? req_comp : *comp; ; 731 : stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); ; 732 : } ; 733 : ; 734 : return (unsigned char*)result; ; 735 : } ; 736 : ; 737 : static stbi__uint16* stbi__load_and_postprocess_16bit(stbi__context* s, int* x, int* y, int* comp, int req_comp) ; 738 : { ; 739 : stbi__result_info ri; ; 740 : void* result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); ; 741 : ; 742 : if (result == NULL) ; 743 : return NULL; ; 744 : ; 745 : // it is the responsibility of the loaders to make sure we get either 8 or 16 bit. ; 746 : STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16); ; 747 : ; 748 : if (ri.bits_per_channel != 16) { ; 749 : result = stbi__convert_8_to_16((stbi_uc*)result, *x, *y, req_comp == 0 ? *comp : req_comp); ; 750 : ri.bits_per_channel = 16; ; 751 : } ; 752 : ; 753 : // @TODO: move stbi__convert_format16 to here ; 754 : // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision ; 755 : ; 756 : if (stbi__vertically_flip_on_load) { ; 757 : int channels = req_comp ? req_comp : *comp; ; 758 : stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); ; 759 : } ; 760 : ; 761 : return (stbi__uint16*)result; ; 762 : } ; 763 : ; 764 : #if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) ; 765 : static void stbi__float_postprocess(float* result, int* x, int* y, int* comp, int req_comp) ; 766 : { ; 767 : if (stbi__vertically_flip_on_load && result != NULL) { ; 768 : int channels = req_comp ? req_comp : *comp; ; 769 : stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); ; 770 : } ; 771 : } ; 772 : #endif ; 773 : ; 774 : #ifndef STBI_NO_STDIO ; 775 : ; 776 : #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) ; 777 : STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char* str, int cbmb, wchar_t* widestr, int cchwide); ; 778 : STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t* widestr, int cchwide, char* str, int cbmb, const char* defchar, int* used_default); ; 779 : #endif ; 780 : ; 781 : #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) ; 782 : STBIDEF int stbi_convert_wchar_to_utf8(char* buffer, size_t bufferlen, const wchar_t* input) ; 783 : { ; 784 : return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int)bufferlen, NULL, NULL); ; 785 : } ; 786 : #endif ; 787 : ; 788 : static FILE* stbi__fopen(char const* filename, char const* mode) ; 789 : { ; 790 : FILE* f; ; 791 : #if defined(_WIN32) && defined(STBI_WINDOWS_UTF8) ; 792 : wchar_t wMode[64]; ; 793 : wchar_t wFilename[1024]; ; 794 : if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename) / sizeof(*wFilename))) ; 795 : return 0; ; 796 : ; 797 : if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode) / sizeof(*wMode))) ; 798 : return 0; ; 799 : ; 800 : #if defined(_MSC_VER) && _MSC_VER >= 1400 ; 801 : if (0 != _wfopen_s(&f, wFilename, wMode)) ; 802 : f = 0; ; 803 : #else ; 804 : f = _wfopen(wFilename, wMode); ; 805 : #endif ; 806 : ; 807 : #elif defined(_MSC_VER) && _MSC_VER >= 1400 ; 808 : if (0 != fopen_s(&f, filename, mode)) 0004d 48 8b 7c 24 30 mov rdi, QWORD PTR f$1[rsp] $LN5@stbi_load: ; 818 : FILE* f = stbi__fopen(filename, "rb"); 00052 48 85 ff test rdi, rdi ; 819 : unsigned char* result; ; 820 : if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); 00055 75 27 jne SHORT $LN2@stbi_load ; 431 : stbi__g_failure_reason = str; 00057 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00060 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00066 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 0006b 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 0006f 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0M@JPDHFAGK@can?8t?5fopen@ 00076 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 819 : unsigned char* result; ; 820 : if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); 0007a 33 c0 xor eax, eax 0007c eb 25 jmp SHORT $LN1@stbi_load $LN2@stbi_load: ; 821 : result = stbi_load_from_file(f, x, y, comp, req_comp); 0007e 4c 8b cd mov r9, rbp 00081 44 89 74 24 20 mov DWORD PTR [rsp+32], r14d 00086 4c 8b c6 mov r8, rsi 00089 48 8b d3 mov rdx, rbx 0008c 48 8b cf mov rcx, rdi 0008f e8 00 00 00 00 call stbi_load_from_file ; 822 : fclose(f); 00094 48 8b cf mov rcx, rdi 00097 48 8b d8 mov rbx, rax 0009a ff 15 00 00 00 00 call QWORD PTR __imp_fclose ; 823 : return result; 000a0 48 8b c3 mov rax, rbx $LN1@stbi_load: ; 824 : } 000a3 48 8b 4c 24 38 mov rcx, QWORD PTR __$ArrayPad$[rsp] 000a8 48 33 cc xor rcx, rsp 000ab e8 00 00 00 00 call __security_check_cookie 000b0 48 83 c4 40 add rsp, 64 ; 00000040H 000b4 41 5e pop r14 000b6 5f pop rdi 000b7 5e pop rsi 000b8 5d pop rbp 000b9 5b pop rbx 000ba c3 ret 0 stbi_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi_load_from_file _TEXT SEGMENT s$ = 48 __$ArrayPad$ = 272 f$ = 336 x$ = 344 y$ = 352 comp$ = 360 req_comp$ = 368 stbi_load_from_file PROC ; COMDAT ; 839 : { $LN9: 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 56 push r14 00007 48 81 ec 20 01 00 00 sub rsp, 288 ; 00000120H 0000e 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00015 48 33 c4 xor rax, rsp 00018 48 89 84 24 10 01 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00020 8b 9c 24 70 01 00 00 mov ebx, DWORD PTR req_comp$[rsp] 00027 49 8b f0 mov rsi, r8 ; 330 : stbi__start_callbacks(s, &stbi__stdio_callbacks, (void*)f); 0002a 4c 8b c1 mov r8, rcx ; 839 : { 0002d 4c 8b f1 mov r14, rcx ; 330 : stbi__start_callbacks(s, &stbi__stdio_callbacks, (void*)f); 00030 48 8d 4c 24 30 lea rcx, QWORD PTR s$[rsp] ; 839 : { 00035 49 8b e9 mov rbp, r9 00038 48 8b fa mov rdi, rdx ; 330 : stbi__start_callbacks(s, &stbi__stdio_callbacks, (void*)f); 0003b e8 00 00 00 00 call stbi__start_callbacks ; 840 : unsigned char* result; ; 841 : stbi__context s; ; 842 : stbi__start_file(&s, f); ; 843 : result = stbi__load_and_postprocess_8bit(&s, x, y, comp, req_comp); 00040 4c 8b cd mov r9, rbp 00043 89 5c 24 20 mov DWORD PTR [rsp+32], ebx 00047 4c 8b c6 mov r8, rsi 0004a 48 8d 4c 24 30 lea rcx, QWORD PTR s$[rsp] 0004f 48 8b d7 mov rdx, rdi 00052 e8 00 00 00 00 call stbi__load_and_postprocess_8bit 00057 48 8b d8 mov rbx, rax ; 844 : if (result) { 0005a 48 85 c0 test rax, rax 0005d 74 20 je SHORT $LN2@stbi_load_ ; 845 : // need to 'unget' all the characters in the IO buffer ; 846 : fseek(f, -(int)(s.img_buffer_end - s.img_buffer), SEEK_CUR); 0005f 8b 94 24 f0 00 00 00 mov edx, DWORD PTR s$[rsp+192] 00066 41 b8 01 00 00 00 mov r8d, 1 0006c 2b 94 24 f8 00 00 00 sub edx, DWORD PTR s$[rsp+200] 00073 49 8b ce mov rcx, r14 00076 ff 15 00 00 00 00 call QWORD PTR __imp_fseek ; 847 : } ; 848 : return result; 0007c 48 8b c3 mov rax, rbx $LN2@stbi_load_: ; 849 : } 0007f 48 8b 8c 24 10 01 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00087 48 33 cc xor rcx, rsp 0008a e8 00 00 00 00 call __security_check_cookie 0008f 48 81 c4 20 01 00 00 add rsp, 288 ; 00000120H 00096 41 5e pop r14 00098 5f pop rdi 00099 5e pop rsi 0009a 5d pop rbp 0009b 5b pop rbx 0009c c3 ret 0 stbi_load_from_file ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__refill_buffer _TEXT SEGMENT s$ = 48 stbi__refill_buffer PROC ; COMDAT ; 1058 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 0000a 44 8b 41 34 mov r8d, DWORD PTR [rcx+52] 0000e 48 8d 79 38 lea rdi, QWORD PTR [rcx+56] 00012 48 8b d9 mov rbx, rcx 00015 48 8b d7 mov rdx, rdi 00018 48 8b 49 28 mov rcx, QWORD PTR [rcx+40] 0001c ff 53 10 call QWORD PTR [rbx+16] ; 1060 : s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); 0001f 8b 93 c0 00 00 00 mov edx, DWORD PTR [rbx+192] 00025 2b 93 d0 00 00 00 sub edx, DWORD PTR [rbx+208] 0002b 01 93 b8 00 00 00 add DWORD PTR [rbx+184], edx 00031 48 89 bb c0 00 00 00 mov QWORD PTR [rbx+192], rdi ; 1061 : if (n == 0) { 00038 85 c0 test eax, eax 0003a 75 1c jne SHORT $LN2@stbi__refi ; 1062 : // at end of file, treat same as if from memory, but need to handle case ; 1063 : // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file ; 1064 : s->read_from_callbacks = 0; 0003c 89 43 30 mov DWORD PTR [rbx+48], eax ; 1065 : s->img_buffer = s->buffer_start; ; 1066 : s->img_buffer_end = s->buffer_start + 1; 0003f 48 8d 43 39 lea rax, QWORD PTR [rbx+57] 00043 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax ; 1067 : *s->img_buffer = 0; 0004a c6 07 00 mov BYTE PTR [rdi], 0 ; 1072 : } ; 1073 : } 0004d 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00052 48 83 c4 20 add rsp, 32 ; 00000020H 00056 5f pop rdi 00057 c3 ret 0 $LN2@stbi__refi: ; 1068 : } ; 1069 : else { ; 1070 : s->img_buffer = s->buffer_start; ; 1071 : s->img_buffer_end = s->buffer_start + n; 00058 48 63 c8 movsxd rcx, eax 0005b 48 83 c1 38 add rcx, 56 ; 00000038H 0005f 48 03 cb add rcx, rbx 00062 48 89 8b c8 00 00 00 mov QWORD PTR [rbx+200], rcx ; 1072 : } ; 1073 : } 00069 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0006e 48 83 c4 20 add rsp, 32 ; 00000020H 00072 5f pop rdi 00073 c3 ret 0 stbi__refill_buffer ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get8 _TEXT SEGMENT s$ = 48 stbi__get8 PROC ; COMDAT ; 1076 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 00006 48 8b 91 c0 00 00 00 mov rdx, QWORD PTR [rcx+192] 0000d 48 8b d9 mov rbx, rcx 00010 48 3b 91 c8 00 00 00 cmp rdx, QWORD PTR [rcx+200] 00017 73 13 jae SHORT $LN2@stbi__get8 ; 1078 : return *s->img_buffer++; 00019 0f b6 02 movzx eax, BYTE PTR [rdx] 0001c 48 ff c2 inc rdx 0001f 48 89 91 c0 00 00 00 mov QWORD PTR [rcx+192], rdx ; 1084 : } 00026 48 83 c4 20 add rsp, 32 ; 00000020H 0002a 5b pop rbx 0002b c3 ret 0 $LN2@stbi__get8: ; 1079 : if (s->read_from_callbacks) { 0002c 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00030 74 69 je SHORT $LN3@stbi__get8 ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 00032 44 8b 41 34 mov r8d, DWORD PTR [rcx+52] 00036 48 8d 51 38 lea rdx, QWORD PTR [rcx+56] 0003a 48 8b 49 28 mov rcx, QWORD PTR [rcx+40] ; 1079 : if (s->read_from_callbacks) { 0003e 48 89 7c 24 30 mov QWORD PTR [rsp+48], rdi ; 1059 : int n = (s->io.read)(s->io_user_data, (char*)s->buffer_start, s->buflen); 00043 ff 53 10 call QWORD PTR [rbx+16] ; 1060 : s->callback_already_read += (int)(s->img_buffer - s->img_buffer_original); 00046 8b 8b c0 00 00 00 mov ecx, DWORD PTR [rbx+192] 0004c 2b 8b d0 00 00 00 sub ecx, DWORD PTR [rbx+208] 00052 01 8b b8 00 00 00 add DWORD PTR [rbx+184], ecx ; 1061 : if (n == 0) { 00058 85 c0 test eax, eax 0005a 75 14 jne SHORT $LN6@stbi__get8 ; 1062 : // at end of file, treat same as if from memory, but need to handle case ; 1063 : // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file ; 1064 : s->read_from_callbacks = 0; 0005c 89 43 30 mov DWORD PTR [rbx+48], eax ; 1065 : s->img_buffer = s->buffer_start; ; 1066 : s->img_buffer_end = s->buffer_start + 1; 0005f 48 8d 43 39 lea rax, QWORD PTR [rbx+57] 00063 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax ; 1067 : *s->img_buffer = 0; 0006a c6 43 38 00 mov BYTE PTR [rbx+56], 0 ; 1068 : } 0006e eb 11 jmp SHORT $LN7@stbi__get8 $LN6@stbi__get8: ; 1069 : else { ; 1070 : s->img_buffer = s->buffer_start; ; 1071 : s->img_buffer_end = s->buffer_start + n; 00070 48 63 c8 movsxd rcx, eax 00073 48 83 c1 38 add rcx, 56 ; 00000038H 00077 48 03 cb add rcx, rbx 0007a 48 89 8b c8 00 00 00 mov QWORD PTR [rbx+200], rcx $LN7@stbi__get8: ; 1080 : stbi__refill_buffer(s); ; 1081 : return *s->img_buffer++; 00081 0f b6 43 38 movzx eax, BYTE PTR [rbx+56] 00085 48 8d 4b 39 lea rcx, QWORD PTR [rbx+57] 00089 48 8b 7c 24 30 mov rdi, QWORD PTR [rsp+48] 0008e 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx ; 1084 : } 00095 48 83 c4 20 add rsp, 32 ; 00000020H 00099 5b pop rbx 0009a c3 ret 0 $LN3@stbi__get8: ; 1082 : } ; 1083 : return 0; 0009b 32 c0 xor al, al ; 1084 : } 0009d 48 83 c4 20 add rsp, 32 ; 00000020H 000a1 5b pop rbx 000a2 c3 ret 0 stbi__get8 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__at_eof _TEXT SEGMENT s$ = 48 stbi__at_eof PROC ; COMDAT ; 1090 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1091 : if (s->io.read) { 00006 48 83 79 10 00 cmp QWORD PTR [rcx+16], 0 0000b 48 8b d9 mov rbx, rcx 0000e 74 22 je SHORT $LN4@stbi__at_e ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 00010 48 8b 49 28 mov rcx, QWORD PTR [rcx+40] 00014 ff 53 20 call QWORD PTR [rbx+32] 00017 85 c0 test eax, eax 00019 75 06 jne SHORT $LN3@stbi__at_e ; 1099 : } 0001b 48 83 c4 20 add rsp, 32 ; 00000020H 0001f 5b pop rbx 00020 c3 ret 0 $LN3@stbi__at_e: ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00021 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00025 75 0b jne SHORT $LN4@stbi__at_e 00027 b8 01 00 00 00 mov eax, 1 ; 1099 : } 0002c 48 83 c4 20 add rsp, 32 ; 00000020H 00030 5b pop rbx 00031 c3 ret 0 $LN4@stbi__at_e: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; 00032 48 8b 8b c8 00 00 00 mov rcx, QWORD PTR [rbx+200] 00039 33 c0 xor eax, eax 0003b 48 39 8b c0 00 00 00 cmp QWORD PTR [rbx+192], rcx 00042 0f 93 c0 setae al ; 1099 : } 00045 48 83 c4 20 add rsp, 32 ; 00000020H 00049 5b pop rbx 0004a c3 ret 0 stbi__at_eof ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__skip _TEXT SEGMENT s$ = 8 n$ = 16 stbi__skip PROC ; COMDAT ; 1106 : { 00000 4c 8b c1 mov r8, rcx ; 1107 : if (n == 0) return; // already there! 00003 85 d2 test edx, edx 00005 74 4b je SHORT $LN1@stbi__skip ; 1108 : if (n < 0) { 00007 79 0f jns SHORT $LN3@stbi__skip ; 1109 : s->img_buffer = s->img_buffer_end; 00009 48 8b 81 c8 00 00 00 mov rax, QWORD PTR [rcx+200] 00010 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax ; 1121 : } 00017 c3 ret 0 $LN3@stbi__skip: ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { 00018 48 83 79 10 00 cmp QWORD PTR [rcx+16], 0 0001d 74 29 je SHORT $LN5@stbi__skip ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 0001f 8b 89 c8 00 00 00 mov ecx, DWORD PTR [rcx+200] 00025 41 2b 88 c0 00 00 00 sub ecx, DWORD PTR [r8+192] ; 1114 : if (blen < n) { 0002c 3b ca cmp ecx, edx 0002e 7d 18 jge SHORT $LN5@stbi__skip ; 1115 : s->img_buffer = s->img_buffer_end; 00030 49 8b 80 c8 00 00 00 mov rax, QWORD PTR [r8+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00037 2b d1 sub edx, ecx 00039 49 8b 48 28 mov rcx, QWORD PTR [r8+40] 0003d 49 89 80 c0 00 00 00 mov QWORD PTR [r8+192], rax 00044 49 ff 60 18 rex_jmp QWORD PTR [r8+24] $LN5@stbi__skip: ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00048 48 63 c2 movsxd rax, edx 0004b 49 01 80 c0 00 00 00 add QWORD PTR [r8+192], rax $LN1@stbi__skip: ; 1121 : } 00052 c3 ret 0 stbi__skip ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__getn _TEXT SEGMENT s$ = 64 buffer$ = 72 n$ = 80 stbi__getn PROC ; COMDAT ; 1128 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1129 : if (s->io.read) { 0001e 48 83 79 10 00 cmp QWORD PTR [rcx+16], 0 00023 48 8d b9 c0 00 00 00 lea rdi, QWORD PTR [rcx+192] 0002a 4d 63 f0 movsxd r14, r8d 0002d 4c 8b e2 mov r12, rdx 00030 48 8b e9 mov rbp, rcx 00033 74 47 je SHORT $LN7@stbi__getn ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00035 44 8b b9 c8 00 00 00 mov r15d, DWORD PTR [rcx+200] 0003c 44 2b 3f sub r15d, DWORD PTR [rdi] ; 1131 : if (blen < n) { 0003f 45 3b fe cmp r15d, r14d 00042 7d 38 jge SHORT $LN7@stbi__getn ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); 00044 48 8b 17 mov rdx, QWORD PTR [rdi] 00047 49 8b cc mov rcx, r12 0004a 49 63 df movsxd rbx, r15d 0004d 4c 8b c3 mov r8, rbx 00050 e8 00 00 00 00 call memcpy ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); 00055 48 8b 4d 28 mov rcx, QWORD PTR [rbp+40] 00059 4a 8d 14 23 lea rdx, QWORD PTR [rbx+r12] 0005d 45 2b f7 sub r14d, r15d 00060 45 8b c6 mov r8d, r14d 00063 ff 55 10 call QWORD PTR [rbp+16] ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; 00066 48 8b 8d c8 00 00 00 mov rcx, QWORD PTR [rbp+200] 0006d 33 d2 xor edx, edx 0006f 41 3b c6 cmp eax, r14d 00072 48 89 0f mov QWORD PTR [rdi], rcx 00075 0f 94 c2 sete dl ; 1139 : return res; 00078 8b c2 mov eax, edx 0007a eb 2a jmp SHORT $LN5@stbi__getn $LN7@stbi__getn: ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { 0007c 48 8b 17 mov rdx, QWORD PTR [rdi] 0007f 49 8b de mov rbx, r14 00082 49 8d 04 16 lea rax, QWORD PTR [r14+rdx] 00086 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0008d 77 15 ja SHORT $LN4@stbi__getn ; 1144 : memcpy(buffer, s->img_buffer, n); 0008f 4c 8b c3 mov r8, rbx 00092 49 8b cc mov rcx, r12 00095 e8 00 00 00 00 call memcpy ; 1145 : s->img_buffer += n; 0009a 48 01 1f add QWORD PTR [rdi], rbx ; 1146 : return 1; 0009d b8 01 00 00 00 mov eax, 1 000a2 eb 02 jmp SHORT $LN5@stbi__getn $LN4@stbi__getn: ; 1147 : } ; 1148 : else ; 1149 : return 0; 000a4 33 c0 xor eax, eax $LN5@stbi__getn: ; 1150 : } 000a6 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 000ab 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 000b0 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 000b5 48 8b 7c 24 58 mov rdi, QWORD PTR [rsp+88] 000ba 48 83 c4 20 add rsp, 32 ; 00000020H 000be 41 5f pop r15 000c0 41 5e pop r14 000c2 41 5c pop r12 000c4 c3 ret 0 stbi__getn ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get16be _TEXT SEGMENT s$ = 48 stbi__get16be PROC ; COMDAT ; 1157 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 1157 : { 00011 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 73 0f jae SHORT $LN4@stbi__get1 ; 1078 : return *s->img_buffer++; 0001d 0f b6 10 movzx edx, BYTE PTR [rax] 00020 48 ff c0 inc rax 00023 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax 0002a eb 23 jmp SHORT $LN15@stbi__get1 $LN4@stbi__get1: ; 1079 : if (s->read_from_callbacks) { 0002c 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00030 74 1b je SHORT $LN5@stbi__get1 ; 1080 : stbi__refill_buffer(s); 00032 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00037 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0003e 0f b6 10 movzx edx, BYTE PTR [rax] 00041 48 ff c0 inc rax 00044 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0004b eb 02 jmp SHORT $LN15@stbi__get1 $LN5@stbi__get1: ; 1082 : } ; 1083 : return 0; 0004d 32 d2 xor dl, dl $LN15@stbi__get1: ; 1158 : int z = stbi__get8(s); 0004f b9 30 00 00 00 mov ecx, 48 ; 00000030H 00054 4c 8b c3 mov r8, rbx 00057 0f b6 fa movzx edi, dl 0005a 4c 8d 0c 19 lea r9, QWORD PTR [rcx+rbx] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0005e 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00065 72 15 jb SHORT $LN16@stbi__get1 ; 1079 : if (s->read_from_callbacks) { 00067 41 83 39 00 cmp DWORD PTR [r9], 0 0006b 74 2f je SHORT $LN9@stbi__get1 ; 1080 : stbi__refill_buffer(s); 0006d 48 8b cb mov rcx, rbx 00070 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00075 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN16@stbi__get1: ; 1159 : return (z << 8) + stbi__get8(s); 0007c 0f b6 08 movzx ecx, BYTE PTR [rax] 0007f 48 ff c0 inc rax 00082 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00089 0f b6 c1 movzx eax, cl 0008c c1 e7 08 shl edi, 8 0008f 03 c7 add eax, edi ; 1160 : } 00091 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00096 48 83 c4 20 add rsp, 32 ; 00000020H 0009a 5f pop rdi 0009b c3 ret 0 $LN9@stbi__get1: 0009c 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 1083 : return 0; 000a1 32 c9 xor cl, cl ; 1159 : return (z << 8) + stbi__get8(s); 000a3 0f b6 c1 movzx eax, cl 000a6 c1 e7 08 shl edi, 8 000a9 03 c7 add eax, edi ; 1160 : } 000ab 48 83 c4 20 add rsp, 32 ; 00000020H 000af 5f pop rdi 000b0 c3 ret 0 stbi__get16be ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get32be _TEXT SEGMENT s$ = 48 stbi__get32be PROC ; COMDAT ; 1167 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 8b d9 mov rbx, rcx ; 1168 : stbi__uint32 z = stbi__get16be(s); 0000d e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00012 48 8b cb mov rcx, rbx 00015 8b f8 mov edi, eax 00017 e8 00 00 00 00 call stbi__get16be ; 1170 : } 0001c 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00021 c1 e7 10 shl edi, 16 00024 03 c7 add eax, edi 00026 48 83 c4 20 add rsp, 32 ; 00000020H 0002a 5f pop rdi 0002b c3 ret 0 stbi__get32be ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get16le _TEXT SEGMENT s$ = 48 stbi__get16le PROC ; COMDAT ; 1177 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 1177 : { 00011 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 73 0f jae SHORT $LN4@stbi__get1 ; 1078 : return *s->img_buffer++; 0001d 0f b6 10 movzx edx, BYTE PTR [rax] 00020 48 ff c0 inc rax 00023 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax 0002a eb 23 jmp SHORT $LN15@stbi__get1 $LN4@stbi__get1: ; 1079 : if (s->read_from_callbacks) { 0002c 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00030 74 1b je SHORT $LN5@stbi__get1 ; 1080 : stbi__refill_buffer(s); 00032 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00037 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0003e 0f b6 10 movzx edx, BYTE PTR [rax] 00041 48 ff c0 inc rax 00044 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0004b eb 02 jmp SHORT $LN15@stbi__get1 $LN5@stbi__get1: ; 1082 : } ; 1083 : return 0; 0004d 32 d2 xor dl, dl $LN15@stbi__get1: ; 1178 : int z = stbi__get8(s); 0004f b9 30 00 00 00 mov ecx, 48 ; 00000030H 00054 4c 8b c3 mov r8, rbx 00057 0f b6 fa movzx edi, dl 0005a 4c 8d 0c 19 lea r9, QWORD PTR [rcx+rbx] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0005e 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00065 72 15 jb SHORT $LN16@stbi__get1 ; 1079 : if (s->read_from_callbacks) { 00067 41 83 39 00 cmp DWORD PTR [r9], 0 0006b 74 2f je SHORT $LN9@stbi__get1 ; 1080 : stbi__refill_buffer(s); 0006d 48 8b cb mov rcx, rbx 00070 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00075 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN16@stbi__get1: ; 1179 : return z + (stbi__get8(s) << 8); 0007c 0f b6 08 movzx ecx, BYTE PTR [rax] 0007f 48 ff c0 inc rax 00082 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00089 0f b6 c1 movzx eax, cl 0008c c1 e0 08 shl eax, 8 0008f 03 c7 add eax, edi ; 1180 : } 00091 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00096 48 83 c4 20 add rsp, 32 ; 00000020H 0009a 5f pop rdi 0009b c3 ret 0 $LN9@stbi__get1: 0009c 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 1083 : return 0; 000a1 32 c9 xor cl, cl ; 1179 : return z + (stbi__get8(s) << 8); 000a3 0f b6 c1 movzx eax, cl 000a6 c1 e0 08 shl eax, 8 000a9 03 c7 add eax, edi ; 1180 : } 000ab 48 83 c4 20 add rsp, 32 ; 00000020H 000af 5f pop rdi 000b0 c3 ret 0 stbi__get16le ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get32le _TEXT SEGMENT s$ = 48 stbi__get32le PROC ; COMDAT ; 1185 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 8b d9 mov rbx, rcx ; 1186 : stbi__uint32 z = stbi__get16le(s); 0000d e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00012 48 8b cb mov rcx, rbx 00015 8b f8 mov edi, eax 00017 e8 00 00 00 00 call stbi__get16le ; 1188 : return z; ; 1189 : } 0001c 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00021 c1 e0 10 shl eax, 16 00024 03 c7 add eax, edi 00026 48 83 c4 20 add rsp, 32 ; 00000020H 0002a 5f pop rdi 0002b c3 ret 0 stbi__get32le ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__compute_y _TEXT SEGMENT r$ = 8 g$ = 16 b$ = 24 stbi__compute_y PROC ; COMDAT ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00000 6b c9 4d imul ecx, ecx, 77 ; 0000004dH 00003 69 c2 96 00 00 00 imul eax, edx, 150 ; 00000096H 00009 03 c1 add eax, ecx 0000b 41 6b c8 1d imul ecx, r8d, 29 0000f 03 c1 add eax, ecx 00011 c1 f8 08 sar eax, 8 ; 1211 : } 00014 c3 ret 0 stbi__compute_y ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__convert_format _TEXT SEGMENT data$ = 80 img_n$ = 88 req_comp$ = 96 x$ = 104 y$ = 112 stbi__convert_format PROC ; COMDAT ; 1218 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 41 54 push r12 00006 41 55 push r13 00008 48 83 ec 20 sub rsp, 32 ; 00000020H 0000c 44 8b 64 24 70 mov r12d, DWORD PTR y$[rsp] 00011 41 8b d9 mov ebx, r9d 00014 41 8b f0 mov esi, r8d 00017 44 8b ea mov r13d, edx 0001a 48 8b e9 mov rbp, rcx ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; 0001d 44 3b c2 cmp r8d, edx 00020 75 0f jne SHORT $LN43@stbi__conv 00022 48 8b c1 mov rax, rcx ; 1259 : } 00025 48 83 c4 20 add rsp, 32 ; 00000020H 00029 41 5d pop r13 0002b 41 5c pop r12 0002d 5e pop rsi 0002e 5d pop rbp 0002f 5b pop rbx 00030 c3 ret 0 $LN43@stbi__conv: 00031 4c 89 7c 24 60 mov QWORD PTR [rsp+96], r15 ; 467 : if (a < 0 || b < 0) return 0; 00036 85 f6 test esi, esi 00038 0f 88 11 04 00 00 js $LN145@stbi__conv 0003e 85 db test ebx, ebx 00040 0f 88 09 04 00 00 js $LN145@stbi__conv ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00046 74 11 je SHORT $LN149@stbi__conv ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00048 33 d2 xor edx, edx 0004a b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0004f f7 f3 div ebx ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00051 3b f0 cmp esi, eax 00053 0f 8f f6 03 00 00 jg $LN145@stbi__conv $LN149@stbi__conv: 00059 8b ce mov ecx, esi 0005b 0f af cb imul ecx, ebx ; 467 : if (a < 0 || b < 0) return 0; 0005e 85 c9 test ecx, ecx 00060 0f 88 e9 03 00 00 js $LN145@stbi__conv 00066 45 85 e4 test r12d, r12d 00069 0f 88 e0 03 00 00 js $LN145@stbi__conv ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0006f 74 12 je SHORT $LN60@stbi__conv ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00071 33 d2 xor edx, edx 00073 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00078 41 f7 f4 div r12d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0007b 3b c8 cmp ecx, eax 0007d 0f 8f cc 03 00 00 jg $LN145@stbi__conv $LN60@stbi__conv: ; 509 : return stbi__malloc(a * b * c + add); 00083 41 0f af cc imul ecx, r12d 00087 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 0008a ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00090 4c 8b f8 mov r15, rax ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { 00093 48 85 c0 test rax, rax 00096 0f 84 b3 03 00 00 je $LN145@stbi__conv 0009c 48 89 7c 24 50 mov QWORD PTR [rsp+80], rdi ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { 000a1 33 ff xor edi, edi 000a3 4c 89 74 24 58 mov QWORD PTR [rsp+88], r14 000a8 45 85 e4 test r12d, r12d 000ab 0f 8e 3e 03 00 00 jle $LN3@stbi__conv 000b1 46 8d 34 ed f6 ff ff ff lea r14d, DWORD PTR [r13*8-10] 000b9 44 03 f6 add r14d, esi 000bc 44 8d 5b ff lea r11d, DWORD PTR [rbx-1] 000c0 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 000c7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL4@stbi__conv: ; 1232 : unsigned char* src = data + j * x * img_n; 000d0 44 8b cf mov r9d, edi ; 1233 : unsigned char* dest = good + j * x * req_comp; 000d3 8b c7 mov eax, edi 000d5 45 0f af cd imul r9d, r13d 000d9 0f af c6 imul eax, esi 000dc 44 0f af cb imul r9d, ebx 000e0 0f af c3 imul eax, ebx 000e3 4c 03 cd add r9, rbp 000e6 49 03 c7 add rax, r15 ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { 000e9 41 83 fe 19 cmp r14d, 25 000ed 0f 87 23 03 00 00 ja $LN57@stbi__conv 000f3 49 63 ce movsxd rcx, r14d 000f6 41 8b 94 88 00 00 00 00 mov edx, DWORD PTR $LN150@stbi__conv[r8+rcx*4] 000fe 49 03 d0 add rdx, r8 00101 ff e2 jmp rdx $LN45@stbi__conv: ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; 00103 41 8b d3 mov edx, r11d 00106 45 85 db test r11d, r11d 00109 0f 88 d5 02 00 00 js $LN2@stbi__conv 0010f 90 npad 1 $LL9@stbi__conv: 00110 83 ea 01 sub edx, 1 00113 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00117 88 08 mov BYTE PTR [rax], cl 00119 4d 8d 49 01 lea r9, QWORD PTR [r9+1] 0011d c6 40 01 ff mov BYTE PTR [rax+1], 255 ; 000000ffH 00121 48 8d 40 02 lea rax, QWORD PTR [rax+2] 00125 79 e9 jns SHORT $LL9@stbi__conv 00127 e9 b8 02 00 00 jmp $LN2@stbi__conv $LN46@stbi__conv: ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; 0012c 41 8b d3 mov edx, r11d 0012f 45 85 db test r11d, r11d 00132 0f 88 ac 02 00 00 js $LN2@stbi__conv 00138 0f 1f 84 00 00 00 00 00 npad 8 $LL12@stbi__conv: 00140 83 ea 01 sub edx, 1 00143 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00147 88 48 02 mov BYTE PTR [rax+2], cl 0014a 4d 8d 49 01 lea r9, QWORD PTR [r9+1] 0014e 88 48 01 mov BYTE PTR [rax+1], cl 00151 88 08 mov BYTE PTR [rax], cl 00153 48 8d 40 03 lea rax, QWORD PTR [rax+3] 00157 79 e7 jns SHORT $LL12@stbi__conv 00159 e9 86 02 00 00 jmp $LN2@stbi__conv $LN47@stbi__conv: ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; 0015e 41 8b d3 mov edx, r11d 00161 45 85 db test r11d, r11d 00164 0f 88 7a 02 00 00 js $LN2@stbi__conv 0016a 66 0f 1f 44 00 00 npad 6 $LL15@stbi__conv: 00170 83 ea 01 sub edx, 1 00173 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00177 88 48 02 mov BYTE PTR [rax+2], cl 0017a 4d 8d 49 01 lea r9, QWORD PTR [r9+1] 0017e 88 48 01 mov BYTE PTR [rax+1], cl 00181 88 08 mov BYTE PTR [rax], cl 00183 c6 40 03 ff mov BYTE PTR [rax+3], 255 ; 000000ffH 00187 48 8d 40 04 lea rax, QWORD PTR [rax+4] 0018b 79 e3 jns SHORT $LL15@stbi__conv 0018d e9 52 02 00 00 jmp $LN2@stbi__conv $LN48@stbi__conv: ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; 00192 41 8b d3 mov edx, r11d 00195 45 85 db test r11d, r11d 00198 0f 88 46 02 00 00 js $LN2@stbi__conv 0019e 66 90 npad 2 $LL18@stbi__conv: 001a0 83 ea 01 sub edx, 1 001a3 41 0f b6 09 movzx ecx, BYTE PTR [r9] 001a7 88 08 mov BYTE PTR [rax], cl 001a9 48 8d 40 01 lea rax, QWORD PTR [rax+1] 001ad 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 001b1 79 ed jns SHORT $LL18@stbi__conv 001b3 e9 2c 02 00 00 jmp $LN2@stbi__conv $LN49@stbi__conv: ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; 001b8 41 8b d3 mov edx, r11d 001bb 45 85 db test r11d, r11d 001be 0f 88 20 02 00 00 js $LN2@stbi__conv 001c4 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL21@stbi__conv: 001d0 83 ea 01 sub edx, 1 001d3 41 0f b6 09 movzx ecx, BYTE PTR [r9] 001d7 88 48 02 mov BYTE PTR [rax+2], cl 001da 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 001de 88 48 01 mov BYTE PTR [rax+1], cl 001e1 88 08 mov BYTE PTR [rax], cl 001e3 48 8d 40 03 lea rax, QWORD PTR [rax+3] 001e7 79 e7 jns SHORT $LL21@stbi__conv 001e9 e9 f6 01 00 00 jmp $LN2@stbi__conv $LN50@stbi__conv: ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; 001ee 41 8b d3 mov edx, r11d 001f1 45 85 db test r11d, r11d 001f4 0f 88 ea 01 00 00 js $LN2@stbi__conv 001fa 66 0f 1f 44 00 00 npad 6 $LL24@stbi__conv: 00200 83 ea 01 sub edx, 1 00203 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00207 88 48 02 mov BYTE PTR [rax+2], cl 0020a 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 0020e 88 48 01 mov BYTE PTR [rax+1], cl 00211 88 08 mov BYTE PTR [rax], cl 00213 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00217 41 0f b6 49 ff movzx ecx, BYTE PTR [r9-1] 0021c 88 48 ff mov BYTE PTR [rax-1], cl 0021f 79 df jns SHORT $LL24@stbi__conv 00221 e9 be 01 00 00 jmp $LN2@stbi__conv $LN51@stbi__conv: ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; 00226 41 8b d3 mov edx, r11d 00229 45 85 db test r11d, r11d 0022c 0f 88 b2 01 00 00 js $LN2@stbi__conv $LL27@stbi__conv: 00232 83 ea 01 sub edx, 1 00235 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00239 88 08 mov BYTE PTR [rax], cl 0023b 48 8d 40 04 lea rax, QWORD PTR [rax+4] 0023f 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 00244 4d 8d 49 03 lea r9, QWORD PTR [r9+3] 00248 88 48 fd mov BYTE PTR [rax-3], cl 0024b 41 0f b6 49 ff movzx ecx, BYTE PTR [r9-1] 00250 88 48 fe mov BYTE PTR [rax-2], cl 00253 c6 40 ff ff mov BYTE PTR [rax-1], 255 ; 000000ffH 00257 79 d9 jns SHORT $LL27@stbi__conv 00259 e9 86 01 00 00 jmp $LN2@stbi__conv $LN52@stbi__conv: ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 0025e 45 8b d3 mov r10d, r11d 00261 45 85 db test r11d, r11d 00264 0f 88 7a 01 00 00 js $LN2@stbi__conv 0026a 66 0f 1f 44 00 00 npad 6 $LL30@stbi__conv: 00270 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 00275 48 8d 40 01 lea rax, QWORD PTR [rax+1] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00279 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 00280 41 0f b6 49 02 movzx ecx, BYTE PTR [r9+2] 00285 4d 8d 49 03 lea r9, QWORD PTR [r9+3] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00289 6b d1 1d imul edx, ecx, 29 ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 0028c 41 0f b6 49 fd movzx ecx, BYTE PTR [r9-3] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00291 44 03 c2 add r8d, edx 00294 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00297 44 03 c2 add r8d, edx 0029a 41 c1 e8 08 shr r8d, 8 ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 0029e 41 83 ea 01 sub r10d, 1 002a2 44 88 40 ff mov BYTE PTR [rax-1], r8b 002a6 79 c8 jns SHORT $LL30@stbi__conv 002a8 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 002af e9 30 01 00 00 jmp $LN2@stbi__conv $LN53@stbi__conv: ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; 002b4 45 8b d3 mov r10d, r11d 002b7 45 85 db test r11d, r11d 002ba 0f 88 24 01 00 00 js $LN2@stbi__conv $LL33@stbi__conv: 002c0 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 002c5 48 8d 40 02 lea rax, QWORD PTR [rax+2] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 002c9 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; 002d0 41 0f b6 49 02 movzx ecx, BYTE PTR [r9+2] 002d5 4d 8d 49 03 lea r9, QWORD PTR [r9+3] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 002d9 6b d1 1d imul edx, ecx, 29 ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; 002dc 41 0f b6 49 fd movzx ecx, BYTE PTR [r9-3] 002e1 c6 40 ff ff mov BYTE PTR [rax-1], 255 ; 000000ffH ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 002e5 44 03 c2 add r8d, edx 002e8 6b d1 4d imul edx, ecx, 77 ; 0000004dH 002eb 44 03 c2 add r8d, edx 002ee 41 c1 e8 08 shr r8d, 8 ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; 002f2 41 83 ea 01 sub r10d, 1 002f6 44 88 40 fe mov BYTE PTR [rax-2], r8b 002fa 79 c4 jns SHORT $LL33@stbi__conv 002fc 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 00303 e9 dc 00 00 00 jmp $LN2@stbi__conv $LN54@stbi__conv: ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 00308 45 8b d3 mov r10d, r11d 0030b 45 85 db test r11d, r11d 0030e 0f 88 d0 00 00 00 js $LN2@stbi__conv 00314 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL36@stbi__conv: 00320 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 00325 48 8d 40 01 lea rax, QWORD PTR [rax+1] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00329 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 00330 41 0f b6 49 02 movzx ecx, BYTE PTR [r9+2] 00335 4d 8d 49 04 lea r9, QWORD PTR [r9+4] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00339 6b d1 1d imul edx, ecx, 29 ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 0033c 41 0f b6 49 fc movzx ecx, BYTE PTR [r9-4] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00341 44 03 c2 add r8d, edx 00344 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00347 44 03 c2 add r8d, edx 0034a 41 c1 e8 08 shr r8d, 8 ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; 0034e 41 83 ea 01 sub r10d, 1 00352 44 88 40 ff mov BYTE PTR [rax-1], r8b 00356 79 c8 jns SHORT $LL36@stbi__conv 00358 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 0035f e9 80 00 00 00 jmp $LN2@stbi__conv $LN55@stbi__conv: ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; 00364 45 8b d3 mov r10d, r11d 00367 45 85 db test r11d, r11d 0036a 78 78 js SHORT $LN2@stbi__conv 0036c 0f 1f 40 00 npad 4 $LL39@stbi__conv: 00370 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 00375 48 8d 40 02 lea rax, QWORD PTR [rax+2] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00379 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; 00380 41 0f b6 49 02 movzx ecx, BYTE PTR [r9+2] 00385 4d 8d 49 04 lea r9, QWORD PTR [r9+4] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00389 6b d1 1d imul edx, ecx, 29 ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; 0038c 41 0f b6 49 fc movzx ecx, BYTE PTR [r9-4] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00391 44 03 c2 add r8d, edx 00394 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00397 44 03 c2 add r8d, edx 0039a 41 c1 e8 08 shr r8d, 8 ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; 0039e 41 83 ea 01 sub r10d, 1 003a2 44 88 40 fe mov BYTE PTR [rax-2], r8b 003a6 41 0f b6 49 ff movzx ecx, BYTE PTR [r9-1] 003ab 88 48 ff mov BYTE PTR [rax-1], cl 003ae 79 c0 jns SHORT $LL39@stbi__conv 003b0 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 003b7 eb 2b jmp SHORT $LN2@stbi__conv $LN56@stbi__conv: ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; 003b9 41 8b d3 mov edx, r11d 003bc 45 85 db test r11d, r11d 003bf 78 23 js SHORT $LN2@stbi__conv $LL42@stbi__conv: 003c1 83 ea 01 sub edx, 1 003c4 41 0f b6 09 movzx ecx, BYTE PTR [r9] 003c8 88 08 mov BYTE PTR [rax], cl 003ca 48 8d 40 03 lea rax, QWORD PTR [rax+3] 003ce 41 0f b6 49 01 movzx ecx, BYTE PTR [r9+1] 003d3 4d 8d 49 04 lea r9, QWORD PTR [r9+4] 003d7 88 48 fe mov BYTE PTR [rax-2], cl 003da 41 0f b6 49 fe movzx ecx, BYTE PTR [r9-2] 003df 88 48 ff mov BYTE PTR [rax-1], cl 003e2 79 dd jns SHORT $LL42@stbi__conv $LN2@stbi__conv: ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { 003e4 ff c7 inc edi 003e6 41 3b fc cmp edi, r12d 003e9 0f 8c e1 fc ff ff jl $LL4@stbi__conv $LN3@stbi__conv: ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); 003ef 48 8b cd mov rcx, rbp 003f2 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 1258 : return good; 003f8 49 8b c7 mov rax, r15 $LN179@stbi__conv: 003fb 4c 8b 74 24 58 mov r14, QWORD PTR [rsp+88] 00400 48 8b 7c 24 50 mov rdi, QWORD PTR [rsp+80] 00405 4c 8b 7c 24 60 mov r15, QWORD PTR [rsp+96] ; 1259 : } 0040a 48 83 c4 20 add rsp, 32 ; 00000020H 0040e 41 5d pop r13 00410 41 5c pop r12 00412 5e pop rsi 00413 5d pop rbp 00414 5b pop rbx 00415 c3 ret 0 $LN57@stbi__conv: ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); 00416 48 8b cd mov rcx, rbp 00419 ff 15 00 00 00 00 call QWORD PTR __imp_free 0041f 49 8b cf mov rcx, r15 00422 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 00428 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0042e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00437 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0043c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00440 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@MHDBFHD@unsupported@ 00447 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); 0044b 33 c0 xor eax, eax 0044d eb ac jmp SHORT $LN179@stbi__conv $LN145@stbi__conv: ; 1227 : STBI_FREE(data); 0044f 48 8b cd mov rcx, rbp 00452 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 00458 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0045e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00467 4c 8b 7c 24 60 mov r15, QWORD PTR [rsp+96] 0046c b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00471 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00475 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 0047c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); 00480 33 c0 xor eax, eax ; 1259 : } 00482 48 83 c4 20 add rsp, 32 ; 00000020H 00486 41 5d pop r13 00488 41 5c pop r12 0048a 5e pop rsi 0048b 5d pop rbp 0048c 5b pop rbx 0048d c3 ret 0 0048e 66 90 npad 2 $LN150@stbi__conv: 00490 00 00 00 00 DD $LN45@stbi__conv 00494 00 00 00 00 DD $LN46@stbi__conv 00498 00 00 00 00 DD $LN47@stbi__conv 0049c 00 00 00 00 DD $LN57@stbi__conv 004a0 00 00 00 00 DD $LN57@stbi__conv 004a4 00 00 00 00 DD $LN57@stbi__conv 004a8 00 00 00 00 DD $LN57@stbi__conv 004ac 00 00 00 00 DD $LN48@stbi__conv 004b0 00 00 00 00 DD $LN57@stbi__conv 004b4 00 00 00 00 DD $LN49@stbi__conv 004b8 00 00 00 00 DD $LN50@stbi__conv 004bc 00 00 00 00 DD $LN57@stbi__conv 004c0 00 00 00 00 DD $LN57@stbi__conv 004c4 00 00 00 00 DD $LN57@stbi__conv 004c8 00 00 00 00 DD $LN57@stbi__conv 004cc 00 00 00 00 DD $LN52@stbi__conv 004d0 00 00 00 00 DD $LN53@stbi__conv 004d4 00 00 00 00 DD $LN57@stbi__conv 004d8 00 00 00 00 DD $LN51@stbi__conv 004dc 00 00 00 00 DD $LN57@stbi__conv 004e0 00 00 00 00 DD $LN57@stbi__conv 004e4 00 00 00 00 DD $LN57@stbi__conv 004e8 00 00 00 00 DD $LN57@stbi__conv 004ec 00 00 00 00 DD $LN54@stbi__conv 004f0 00 00 00 00 DD $LN55@stbi__conv 004f4 00 00 00 00 DD $LN56@stbi__conv stbi__convert_format ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__compute_y_16 _TEXT SEGMENT r$ = 8 g$ = 16 b$ = 24 stbi__compute_y_16 PROC ; COMDAT ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00000 6b c9 4d imul ecx, ecx, 77 ; 0000004dH 00003 69 c2 96 00 00 00 imul eax, edx, 150 ; 00000096H 00009 03 c1 add eax, ecx 0000b 41 6b c8 1d imul ecx, r8d, 29 0000f 03 c1 add eax, ecx 00011 c1 f8 08 sar eax, 8 ; 1268 : } 00014 c3 ret 0 stbi__compute_y_16 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__convert_format16 _TEXT SEGMENT data$ = 64 img_n$ = 72 req_comp$ = 80 x$ = 88 y$ = 96 stbi__convert_format16 PROC ; COMDAT ; 1275 : { 00000 48 89 6c 24 20 mov QWORD PTR [rsp+32], rbp 00005 56 push rsi 00006 57 push rdi 00007 41 54 push r12 00009 48 83 ec 20 sub rsp, 32 ; 00000020H 0000d 41 8b f1 mov esi, r9d 00010 41 8b e8 mov ebp, r8d 00013 44 8b e2 mov r12d, edx 00016 48 8b f9 mov rdi, rcx ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; 00019 44 3b c2 cmp r8d, edx 0001c 75 11 jne SHORT $LN43@stbi__conv 0001e 48 8b c1 mov rax, rcx ; 1316 : } 00021 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 00026 48 83 c4 20 add rsp, 32 ; 00000020H 0002a 41 5c pop r12 0002c 5f pop rdi 0002d 5e pop rsi 0002e c3 ret 0 $LN43@stbi__conv: ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); 0002f 8b c5 mov eax, ebp 00031 4c 89 74 24 48 mov QWORD PTR [rsp+72], r14 00036 0f af c6 imul eax, esi 00039 0f af 44 24 60 imul eax, DWORD PTR y$[rsp] 0003e 8d 0c 00 lea ecx, DWORD PTR [rax+rax] ; 438 : return STBI_MALLOC(size); 00041 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00047 4c 8b f0 mov r14, rax ; 1283 : if (good == NULL) { 0004a 48 85 c0 test rax, rax 0004d 75 33 jne SHORT $LN44@stbi__conv ; 1284 : STBI_FREE(data); 0004f 48 8b cf mov rcx, rdi 00052 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 00058 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0005e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00067 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0006c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00070 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00077 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); 0007b 33 c0 xor eax, eax 0007d e9 56 02 00 00 jmp $LN150@stbi__conv $LN44@stbi__conv: 00082 48 89 5c 24 40 mov QWORD PTR [rsp+64], rbx ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { 00087 33 db xor ebx, ebx 00089 4c 89 7c 24 50 mov QWORD PTR [rsp+80], r15 0008e 39 5c 24 60 cmp DWORD PTR y$[rsp], ebx 00092 0f 8e 2a 02 00 00 jle $LN3@stbi__conv 00098 46 8d 3c e5 f6 ff ff ff lea r15d, DWORD PTR [r12*8-10] 000a0 41 b8 ff ff 00 00 mov r8d, 65535 ; 0000ffffH 000a6 44 03 fd add r15d, ebp 000a9 44 8d 5e ff lea r11d, DWORD PTR [rsi-1] 000ad 4c 8d 15 00 00 00 00 lea r10, OFFSET FLAT:__ImageBase 000b4 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__conv: ; 1289 : stbi__uint16* src = data + j * x * img_n; 000c0 8b c3 mov eax, ebx 000c2 41 0f af c4 imul eax, r12d 000c6 0f af c6 imul eax, esi 000c9 4c 8d 0c 47 lea r9, QWORD PTR [rdi+rax*2] ; 1290 : stbi__uint16* dest = good + j * x * req_comp; 000cd 8b c3 mov eax, ebx 000cf 0f af c5 imul eax, ebp 000d2 0f af c6 imul eax, esi 000d5 49 8d 04 46 lea rax, QWORD PTR [r14+rax*2] ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { 000d9 41 83 ff 19 cmp r15d, 25 000dd 0f 87 58 03 00 00 ja $LN57@stbi__conv 000e3 49 63 cf movsxd rcx, r15d 000e6 41 8b 94 8a 00 00 00 00 mov edx, DWORD PTR $LN125@stbi__conv[r10+rcx*4] 000ee 49 03 d2 add rdx, r10 000f1 ff e2 jmp rdx $LN45@stbi__conv: ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; 000f3 41 8b d3 mov edx, r11d 000f6 45 85 db test r11d, r11d 000f9 0f 88 b7 01 00 00 js $LN2@stbi__conv 000ff 90 npad 1 $LL9@stbi__conv: 00100 83 ea 01 sub edx, 1 00103 41 0f b7 09 movzx ecx, WORD PTR [r9] 00107 66 89 08 mov WORD PTR [rax], cx 0010a 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 0010e 66 44 89 40 02 mov WORD PTR [rax+2], r8w 00113 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00117 79 e7 jns SHORT $LL9@stbi__conv 00119 e9 98 01 00 00 jmp $LN2@stbi__conv $LN46@stbi__conv: ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; 0011e 41 8b d3 mov edx, r11d 00121 45 85 db test r11d, r11d 00124 0f 88 8c 01 00 00 js $LN2@stbi__conv 0012a 66 0f 1f 44 00 00 npad 6 $LL12@stbi__conv: 00130 83 ea 01 sub edx, 1 00133 41 0f b7 09 movzx ecx, WORD PTR [r9] 00137 66 89 48 04 mov WORD PTR [rax+4], cx 0013b 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 0013f 66 89 48 02 mov WORD PTR [rax+2], cx 00143 66 89 08 mov WORD PTR [rax], cx 00146 48 8d 40 06 lea rax, QWORD PTR [rax+6] 0014a 79 e4 jns SHORT $LL12@stbi__conv 0014c e9 65 01 00 00 jmp $LN2@stbi__conv $LN47@stbi__conv: ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; 00151 41 8b d3 mov edx, r11d 00154 45 85 db test r11d, r11d 00157 0f 88 59 01 00 00 js $LN2@stbi__conv 0015d 0f 1f 00 npad 3 $LL15@stbi__conv: 00160 83 ea 01 sub edx, 1 00163 41 0f b7 09 movzx ecx, WORD PTR [r9] 00167 66 89 48 04 mov WORD PTR [rax+4], cx 0016b 4d 8d 49 02 lea r9, QWORD PTR [r9+2] 0016f 66 89 48 02 mov WORD PTR [rax+2], cx 00173 66 89 08 mov WORD PTR [rax], cx 00176 66 44 89 40 06 mov WORD PTR [rax+6], r8w 0017b 48 8d 40 08 lea rax, QWORD PTR [rax+8] 0017f 79 df jns SHORT $LL15@stbi__conv 00181 e9 30 01 00 00 jmp $LN2@stbi__conv $LN48@stbi__conv: ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; 00186 41 8b d3 mov edx, r11d 00189 45 85 db test r11d, r11d 0018c 0f 88 24 01 00 00 js $LN2@stbi__conv $LL18@stbi__conv: 00192 83 ea 01 sub edx, 1 00195 41 0f b7 09 movzx ecx, WORD PTR [r9] 00199 66 89 08 mov WORD PTR [rax], cx 0019c 48 8d 40 02 lea rax, QWORD PTR [rax+2] 001a0 4d 8d 49 04 lea r9, QWORD PTR [r9+4] 001a4 79 ec jns SHORT $LL18@stbi__conv 001a6 e9 0b 01 00 00 jmp $LN2@stbi__conv $LN49@stbi__conv: ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; 001ab 41 8b d3 mov edx, r11d 001ae 45 85 db test r11d, r11d 001b1 0f 88 ff 00 00 00 js $LN2@stbi__conv 001b7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL21@stbi__conv: 001c0 83 ea 01 sub edx, 1 001c3 41 0f b7 09 movzx ecx, WORD PTR [r9] 001c7 66 89 48 04 mov WORD PTR [rax+4], cx 001cb 4d 8d 49 04 lea r9, QWORD PTR [r9+4] 001cf 66 89 48 02 mov WORD PTR [rax+2], cx 001d3 66 89 08 mov WORD PTR [rax], cx 001d6 48 8d 40 06 lea rax, QWORD PTR [rax+6] 001da 79 e4 jns SHORT $LL21@stbi__conv 001dc e9 d5 00 00 00 jmp $LN2@stbi__conv $LN50@stbi__conv: ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; 001e1 41 8b d3 mov edx, r11d 001e4 45 85 db test r11d, r11d 001e7 0f 88 c9 00 00 00 js $LN2@stbi__conv 001ed 0f 1f 00 npad 3 $LL24@stbi__conv: 001f0 83 ea 01 sub edx, 1 001f3 41 0f b7 09 movzx ecx, WORD PTR [r9] 001f7 66 89 48 04 mov WORD PTR [rax+4], cx 001fb 4d 8d 49 04 lea r9, QWORD PTR [r9+4] 001ff 66 89 48 02 mov WORD PTR [rax+2], cx 00203 66 89 08 mov WORD PTR [rax], cx 00206 48 8d 40 08 lea rax, QWORD PTR [rax+8] 0020a 41 0f b7 49 fe movzx ecx, WORD PTR [r9-2] 0020f 66 89 48 fe mov WORD PTR [rax-2], cx 00213 79 db jns SHORT $LL24@stbi__conv 00215 e9 9c 00 00 00 jmp $LN2@stbi__conv $LN51@stbi__conv: ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; 0021a 41 8b d3 mov edx, r11d 0021d 45 85 db test r11d, r11d 00220 0f 88 90 00 00 00 js $LN2@stbi__conv 00226 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL27@stbi__conv: 00230 83 ea 01 sub edx, 1 00233 41 0f b7 09 movzx ecx, WORD PTR [r9] 00237 66 89 08 mov WORD PTR [rax], cx 0023a 48 8d 40 08 lea rax, QWORD PTR [rax+8] 0023e 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 00243 4d 8d 49 06 lea r9, QWORD PTR [r9+6] 00247 66 89 48 fa mov WORD PTR [rax-6], cx 0024b 41 0f b7 49 fe movzx ecx, WORD PTR [r9-2] 00250 66 89 48 fc mov WORD PTR [rax-4], cx 00254 66 44 89 40 fe mov WORD PTR [rax-2], r8w 00259 79 d5 jns SHORT $LL27@stbi__conv 0025b eb 59 jmp SHORT $LN2@stbi__conv $LN52@stbi__conv: ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 0025d 45 8b d3 mov r10d, r11d 00260 45 85 db test r11d, r11d 00263 78 4a js SHORT $LN129@stbi__conv 00265 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL30@stbi__conv: 00270 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 00275 48 8d 40 02 lea rax, QWORD PTR [rax+2] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00279 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 00280 41 0f b7 49 04 movzx ecx, WORD PTR [r9+4] 00285 4d 8d 49 06 lea r9, QWORD PTR [r9+6] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00289 6b d1 1d imul edx, ecx, 29 ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 0028c 41 0f b7 49 fa movzx ecx, WORD PTR [r9-6] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00291 44 03 c2 add r8d, edx 00294 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00297 44 03 c2 add r8d, edx 0029a 41 c1 e8 08 shr r8d, 8 ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 0029e 41 83 ea 01 sub r10d, 1 002a2 66 44 89 40 fe mov WORD PTR [rax-2], r8w 002a7 79 c7 jns SHORT $LL30@stbi__conv $LN154@stbi__conv: ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { 002a9 41 b8 ff ff 00 00 mov r8d, 65535 ; 0000ffffH $LN129@stbi__conv: 002af 4c 8d 15 00 00 00 00 lea r10, OFFSET FLAT:__ImageBase $LN2@stbi__conv: 002b6 ff c3 inc ebx 002b8 3b 5c 24 60 cmp ebx, DWORD PTR y$[rsp] 002bc 0f 8c fe fd ff ff jl $LL4@stbi__conv $LN3@stbi__conv: ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); 002c2 48 8b cf mov rcx, rdi 002c5 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 1315 : return good; 002cb 49 8b c6 mov rax, r14 $LN152@stbi__conv: 002ce 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 002d3 4c 8b 7c 24 50 mov r15, QWORD PTR [rsp+80] $LN150@stbi__conv: 002d8 4c 8b 74 24 48 mov r14, QWORD PTR [rsp+72] ; 1316 : } 002dd 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 002e2 48 83 c4 20 add rsp, 32 ; 00000020H 002e6 41 5c pop r12 002e8 5f pop rdi 002e9 5e pop rsi 002ea c3 ret 0 $LN53@stbi__conv: ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; 002eb 45 8b d3 mov r10d, r11d 002ee 45 85 db test r11d, r11d 002f1 78 bc js SHORT $LN129@stbi__conv 002f3 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL33@stbi__conv: 00300 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 00305 48 8d 40 04 lea rax, QWORD PTR [rax+4] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00309 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; 00310 41 0f b7 49 04 movzx ecx, WORD PTR [r9+4] 00315 4d 8d 49 06 lea r9, QWORD PTR [r9+6] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00319 6b d1 1d imul edx, ecx, 29 ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; 0031c 41 0f b7 49 fa movzx ecx, WORD PTR [r9-6] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00321 44 03 c2 add r8d, edx 00324 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00327 44 03 c2 add r8d, edx 0032a 41 c1 e8 08 shr r8d, 8 ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; 0032e 41 83 ea 01 sub r10d, 1 00332 66 44 89 40 fc mov WORD PTR [rax-4], r8w 00337 41 b8 ff ff 00 00 mov r8d, 65535 ; 0000ffffH 0033d 66 44 89 40 fe mov WORD PTR [rax-2], r8w 00342 79 bc jns SHORT $LL33@stbi__conv 00344 e9 66 ff ff ff jmp $LN129@stbi__conv $LN54@stbi__conv: ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 00349 45 8b d3 mov r10d, r11d 0034c 45 85 db test r11d, r11d 0034f 0f 88 5a ff ff ff js $LN129@stbi__conv 00355 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL36@stbi__conv: 00360 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 00365 48 8d 40 02 lea rax, QWORD PTR [rax+2] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00369 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 00370 41 0f b7 49 04 movzx ecx, WORD PTR [r9+4] 00375 4d 8d 49 08 lea r9, QWORD PTR [r9+8] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00379 6b d1 1d imul edx, ecx, 29 ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 0037c 41 0f b7 49 f8 movzx ecx, WORD PTR [r9-8] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00381 44 03 c2 add r8d, edx 00384 6b d1 4d imul edx, ecx, 77 ; 0000004dH 00387 44 03 c2 add r8d, edx 0038a 41 c1 e8 08 shr r8d, 8 ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; 0038e 41 83 ea 01 sub r10d, 1 00392 66 44 89 40 fe mov WORD PTR [rax-2], r8w 00397 79 c7 jns SHORT $LL36@stbi__conv 00399 e9 0b ff ff ff jmp $LN154@stbi__conv $LN55@stbi__conv: ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; 0039e 45 8b d3 mov r10d, r11d 003a1 45 85 db test r11d, r11d 003a4 0f 88 05 ff ff ff js $LN129@stbi__conv 003aa 66 0f 1f 44 00 00 npad 6 $LL39@stbi__conv: 003b0 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 003b5 48 8d 40 04 lea rax, QWORD PTR [rax+4] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 003b9 44 69 c1 96 00 00 00 imul r8d, ecx, 150 ; 00000096H ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; 003c0 41 0f b7 49 04 movzx ecx, WORD PTR [r9+4] 003c5 4d 8d 49 08 lea r9, QWORD PTR [r9+8] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 003c9 6b d1 1d imul edx, ecx, 29 ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; 003cc 41 0f b7 49 f8 movzx ecx, WORD PTR [r9-8] ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); 003d1 44 03 c2 add r8d, edx 003d4 6b d1 4d imul edx, ecx, 77 ; 0000004dH 003d7 44 03 c2 add r8d, edx 003da 41 c1 e8 08 shr r8d, 8 ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; 003de 41 83 ea 01 sub r10d, 1 003e2 66 44 89 40 fc mov WORD PTR [rax-4], r8w 003e7 41 0f b7 49 fe movzx ecx, WORD PTR [r9-2] 003ec 66 89 48 fe mov WORD PTR [rax-2], cx 003f0 79 be jns SHORT $LL39@stbi__conv 003f2 e9 b2 fe ff ff jmp $LN154@stbi__conv $LN56@stbi__conv: ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; 003f7 41 8b d3 mov edx, r11d 003fa 45 85 db test r11d, r11d 003fd 0f 88 b3 fe ff ff js $LN2@stbi__conv 00403 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL42@stbi__conv: 00410 83 ea 01 sub edx, 1 00413 41 0f b7 09 movzx ecx, WORD PTR [r9] 00417 66 89 08 mov WORD PTR [rax], cx 0041a 48 8d 40 06 lea rax, QWORD PTR [rax+6] 0041e 41 0f b7 49 02 movzx ecx, WORD PTR [r9+2] 00423 4d 8d 49 08 lea r9, QWORD PTR [r9+8] 00427 66 89 48 fc mov WORD PTR [rax-4], cx 0042b 41 0f b7 49 fc movzx ecx, WORD PTR [r9-4] 00430 66 89 48 fe mov WORD PTR [rax-2], cx 00434 79 da jns SHORT $LL42@stbi__conv ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; 00436 e9 7b fe ff ff jmp $LN2@stbi__conv $LN57@stbi__conv: ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); 0043b 48 8b cf mov rcx, rdi 0043e ff 15 00 00 00 00 call QWORD PTR __imp_free 00444 49 8b ce mov rcx, r14 00447 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 0044d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00453 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0045c b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00461 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00465 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@MHDBFHD@unsupported@ 0046c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); 00470 33 c0 xor eax, eax 00472 e9 57 fe ff ff jmp $LN152@stbi__conv 00477 90 npad 1 $LN125@stbi__conv: ; 1316 : } 00478 00 00 00 00 DD $LN45@stbi__conv 0047c 00 00 00 00 DD $LN46@stbi__conv 00480 00 00 00 00 DD $LN47@stbi__conv 00484 00 00 00 00 DD $LN57@stbi__conv 00488 00 00 00 00 DD $LN57@stbi__conv 0048c 00 00 00 00 DD $LN57@stbi__conv 00490 00 00 00 00 DD $LN57@stbi__conv 00494 00 00 00 00 DD $LN48@stbi__conv 00498 00 00 00 00 DD $LN57@stbi__conv 0049c 00 00 00 00 DD $LN49@stbi__conv 004a0 00 00 00 00 DD $LN50@stbi__conv 004a4 00 00 00 00 DD $LN57@stbi__conv 004a8 00 00 00 00 DD $LN57@stbi__conv 004ac 00 00 00 00 DD $LN57@stbi__conv 004b0 00 00 00 00 DD $LN57@stbi__conv 004b4 00 00 00 00 DD $LN52@stbi__conv 004b8 00 00 00 00 DD $LN53@stbi__conv 004bc 00 00 00 00 DD $LN57@stbi__conv 004c0 00 00 00 00 DD $LN51@stbi__conv 004c4 00 00 00 00 DD $LN57@stbi__conv 004c8 00 00 00 00 DD $LN57@stbi__conv 004cc 00 00 00 00 DD $LN57@stbi__conv 004d0 00 00 00 00 DD $LN57@stbi__conv 004d4 00 00 00 00 DD $LN54@stbi__conv 004d8 00 00 00 00 DD $LN55@stbi__conv 004dc 00 00 00 00 DD $LN56@stbi__conv stbi__convert_format16 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_to_ldr _TEXT SEGMENT tv691 = 32 tv693 = 40 output$1$ = 48 tv698 = 56 data$ = 160 x$ = 168 y$ = 176 comp$ = 184 stbi__hdr_to_ldr PROC ; COMDAT ; 1347 : { 00000 48 89 4c 24 08 mov QWORD PTR [rsp+8], rcx 00005 53 push rbx 00006 56 push rsi 00007 57 push rdi 00008 48 81 ec 80 00 00 00 sub rsp, 128 ; 00000080H 0000f 49 63 f1 movsxd rsi, r9d 00012 8b da mov ebx, edx 00014 48 8b f9 mov rdi, rcx ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; 00017 48 85 c9 test rcx, rcx 0001a 0f 84 1d 02 00 00 je $LN67@stbi__hdr_ ; 467 : if (a < 0 || b < 0) return 0; 00020 85 d2 test edx, edx 00022 0f 88 e9 01 00 00 js $LN50@stbi__hdr_ 00028 45 85 c0 test r8d, r8d 0002b 0f 88 e0 01 00 00 js $LN50@stbi__hdr_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00031 74 12 je SHORT $LN54@stbi__hdr_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00033 33 d2 xor edx, edx 00035 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0003a 41 f7 f0 div r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0003d 3b d8 cmp ebx, eax 0003f 0f 8f cc 01 00 00 jg $LN50@stbi__hdr_ $LN54@stbi__hdr_: 00045 41 0f af d8 imul ebx, r8d ; 467 : if (a < 0 || b < 0) return 0; 00049 85 db test ebx, ebx 0004b 0f 88 c0 01 00 00 js $LN50@stbi__hdr_ 00051 45 85 c9 test r9d, r9d 00054 0f 88 b7 01 00 00 js $LN50@stbi__hdr_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0005a 74 11 je SHORT $LN53@stbi__hdr_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0005c 33 d2 xor edx, edx 0005e b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00063 f7 f6 div esi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00065 3b d8 cmp ebx, eax 00067 0f 8f a4 01 00 00 jg $LN50@stbi__hdr_ $LN53@stbi__hdr_: ; 509 : return stbi__malloc(a * b * c + add); 0006d 8b c3 mov eax, ebx 0006f 0f af c6 imul eax, esi 00072 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 00075 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 0007b 48 89 44 24 30 mov QWORD PTR output$1$[rsp], rax 00080 4c 8b c0 mov r8, rax ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } 00083 48 85 c0 test rax, rax 00086 0f 84 85 01 00 00 je $LN50@stbi__hdr_ ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; 0008c 40 f6 c6 01 test sil, 1 ; 1355 : for (i = 0; i < x * y; ++i) { 00090 8d 4e ff lea ecx, DWORD PTR [rsi-1] 00093 8b c6 mov eax, esi 00095 0f 44 c1 cmove eax, ecx 00098 89 44 24 20 mov DWORD PTR tv691[rsp], eax 0009c 85 db test ebx, ebx 0009e 0f 8e 54 01 00 00 jle $LN3@stbi__hdr_ 000a4 48 89 ac 24 a8 00 00 00 mov QWORD PTR [rsp+168], rbp 000ac 4c 8d 14 b5 00 00 00 00 lea r10, QWORD PTR [rsi*4] 000b4 4c 89 a4 24 b0 00 00 00 mov QWORD PTR [rsp+176], r12 000bc 4c 8b ce mov r9, rsi 000bf 4c 89 ac 24 b8 00 00 00 mov QWORD PTR [rsp+184], r13 000c7 45 33 ed xor r13d, r13d 000ca 4c 89 74 24 78 mov QWORD PTR [rsp+120], r14 000cf 4d 8b f0 mov r14, r8 000d2 4c 89 7c 24 70 mov QWORD PTR [rsp+112], r15 000d7 4c 8b ff mov r15, rdi 000da 0f 29 74 24 60 movaps XMMWORD PTR [rsp+96], xmm6 000df f3 0f 10 35 00 00 00 00 movss xmm6, DWORD PTR __real@437f0000 000e7 0f 29 7c 24 50 movaps XMMWORD PTR [rsp+80], xmm7 000ec f3 0f 10 3d 00 00 00 00 movss xmm7, DWORD PTR __real@3f000000 000f4 8b d3 mov edx, ebx 000f6 44 0f 29 44 24 40 movaps XMMWORD PTR [rsp+64], xmm8 000fc f2 44 0f 10 05 00 00 00 00 movsd xmm8, QWORD PTR __real@3fdd1745c0000000 00105 4c 63 e0 movsxd r12, eax 00108 4c 89 54 24 38 mov QWORD PTR tv698[rsp], r10 0010d 48 89 54 24 28 mov QWORD PTR tv693[rsp], rdx $LL4@stbi__hdr_: ; 1356 : for (k = 0; k < n; ++k) { 00112 33 ed xor ebp, ebp 00114 4d 85 e4 test r12, r12 00117 7e 62 jle SHORT $LN6@stbi__hdr_ ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; 00119 33 db xor ebx, ebx 0011b 49 8b ff mov rdi, r15 0011e 8b e8 mov ebp, eax $LL7@stbi__hdr_: 00120 f3 0f 10 07 movss xmm0, DWORD PTR [rdi] 00124 41 0f 28 c8 movaps xmm1, xmm8 00128 0f 5a c0 cvtps2pd xmm0, xmm0 0012b e8 00 00 00 00 call pow 00130 0f 57 d2 xorps xmm2, xmm2 00133 0f 57 c9 xorps xmm1, xmm1 00136 f2 0f 5a d0 cvtsd2ss xmm2, xmm0 0013a 48 83 c7 04 add rdi, 4 ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; 0013e 0f 28 c6 movaps xmm0, xmm6 00141 f3 0f 59 d6 mulss xmm2, xmm6 00145 f3 0f 58 d7 addss xmm2, xmm7 00149 f3 0f 5f ca maxss xmm1, xmm2 0014d f3 0f 5d c1 minss xmm0, xmm1 ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); 00151 f3 0f 2c c0 cvttss2si eax, xmm0 00155 41 88 04 1e mov BYTE PTR [r14+rbx], al 00159 48 ff c3 inc rbx 0015c 49 3b dc cmp rbx, r12 0015f 7c bf jl SHORT $LL7@stbi__hdr_ 00161 48 8b 54 24 28 mov rdx, QWORD PTR tv693[rsp] 00166 4c 8b ce mov r9, rsi 00169 48 8b bc 24 a0 00 00 00 mov rdi, QWORD PTR data$[rsp] 00171 4c 8b 44 24 30 mov r8, QWORD PTR output$1$[rsp] 00176 4c 8b 54 24 38 mov r10, QWORD PTR tv698[rsp] $LN6@stbi__hdr_: ; 1361 : } ; 1362 : if (k < comp) { 0017b 3b ee cmp ebp, esi 0017d 7d 2b jge SHORT $LN2@stbi__hdr_ ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; 0017f 41 8b c5 mov eax, r13d 00182 0f 57 c9 xorps xmm1, xmm1 00185 03 c5 add eax, ebp 00187 48 63 c8 movsxd rcx, eax 0018a f3 0f 10 04 8f movss xmm0, DWORD PTR [rdi+rcx*4] 0018f f3 0f 59 c6 mulss xmm0, xmm6 00193 f3 0f 58 c7 addss xmm0, xmm7 ; 1364 : if (z < 0) z = 0; 00197 f3 0f 5f c8 maxss xmm1, xmm0 ; 1365 : if (z > 255) z = 255; 0019b 0f 28 c6 movaps xmm0, xmm6 0019e f3 0f 5d c1 minss xmm0, xmm1 ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); 001a2 f3 0f 2c c0 cvttss2si eax, xmm0 001a6 42 88 04 01 mov BYTE PTR [rcx+r8], al $LN2@stbi__hdr_: ; 1355 : for (i = 0; i < x * y; ++i) { 001aa 8b 44 24 20 mov eax, DWORD PTR tv691[rsp] 001ae 44 03 ee add r13d, esi 001b1 4d 03 fa add r15, r10 001b4 4d 03 f1 add r14, r9 001b7 48 83 ea 01 sub rdx, 1 001bb 48 89 54 24 28 mov QWORD PTR tv693[rsp], rdx 001c0 0f 85 4c ff ff ff jne $LL4@stbi__hdr_ 001c6 44 0f 28 44 24 40 movaps xmm8, XMMWORD PTR [rsp+64] 001cc 0f 28 7c 24 50 movaps xmm7, XMMWORD PTR [rsp+80] 001d1 0f 28 74 24 60 movaps xmm6, XMMWORD PTR [rsp+96] 001d6 4c 8b 7c 24 70 mov r15, QWORD PTR [rsp+112] 001db 4c 8b 74 24 78 mov r14, QWORD PTR [rsp+120] 001e0 4c 8b ac 24 b8 00 00 00 mov r13, QWORD PTR [rsp+184] 001e8 4c 8b a4 24 b0 00 00 00 mov r12, QWORD PTR [rsp+176] 001f0 48 8b ac 24 a8 00 00 00 mov rbp, QWORD PTR [rsp+168] $LN3@stbi__hdr_: ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); 001f8 48 8b cf mov rcx, rdi 001fb ff 15 00 00 00 00 call QWORD PTR __imp_free ; 1370 : return output; 00201 48 8b 44 24 30 mov rax, QWORD PTR output$1$[rsp] ; 1371 : } 00206 48 81 c4 80 00 00 00 add rsp, 128 ; 00000080H 0020d 5f pop rdi 0020e 5e pop rsi 0020f 5b pop rbx 00210 c3 ret 0 $LN50@stbi__hdr_: ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } 00211 48 8b cf mov rcx, rdi 00214 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 0021a 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00223 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00229 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 0022e 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 00232 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00239 48 89 04 0a mov QWORD PTR [rdx+rcx], rax $LN67@stbi__hdr_: ; 1371 : } 0023d 33 c0 xor eax, eax 0023f 48 81 c4 80 00 00 00 add rsp, 128 ; 00000080H 00246 5f pop rdi 00247 5e pop rsi 00248 5b pop rbx 00249 c3 ret 0 stbi__hdr_to_ldr ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__build_huffman _TEXT SEGMENT h$ = 64 count$ = 72 stbi__build_huffman PROC ; COMDAT ; 1466 : { 00000 40 53 push rbx 00002 56 push rsi 00003 41 57 push r15 00005 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1467 : int i, j, k = 0; 00009 33 f6 xor esi, esi 0000b 4c 8b f9 mov r15, rcx 0000e 44 8b d6 mov r10d, esi ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { 00011 8b de mov ebx, esi 00013 8b c6 mov eax, esi 00015 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL4@stbi__buil: ; 1471 : for (j = 0; j < count[i]; ++j) { 00020 4c 63 c3 movsxd r8, ebx 00023 44 8b ce mov r9d, esi 00026 46 8b 1c 82 mov r11d, DWORD PTR [rdx+r8*4] 0002a 45 85 db test r11d, r11d 0002d 7e 25 jle SHORT $LN2@stbi__buil 0002f 8d 4b 01 lea ecx, DWORD PTR [rbx+1] $LL7@stbi__buil: ; 1472 : h->size[k++] = (stbi_uc)(i + 1); 00032 41 88 8c 07 00 05 00 00 mov BYTE PTR [r15+rax+1280], cl 0003a 41 ff c2 inc r10d 0003d 48 ff c0 inc rax ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); 00040 48 3d 01 01 00 00 cmp rax, 257 ; 00000101H 00046 0f 8d 51 01 00 00 jge $LN34@stbi__buil ; 1471 : for (j = 0; j < count[i]; ++j) { 0004c 41 ff c1 inc r9d 0004f 45 3b cb cmp r9d, r11d 00052 7c de jl SHORT $LL7@stbi__buil $LN2@stbi__buil: ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { 00054 ff c3 inc ebx 00056 83 fb 10 cmp ebx, 16 00059 7c c5 jl SHORT $LL4@stbi__buil ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; 0005b 49 63 c2 movsxd rax, r10d ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; 0005e 8b d6 mov edx, esi 00060 48 89 7c 24 48 mov QWORD PTR [rsp+72], rdi ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { 00065 41 ba 01 00 00 00 mov r10d, 1 0006b 4c 89 74 24 50 mov QWORD PTR [rsp+80], r14 00070 8b de mov ebx, esi 00072 4c 8b ce mov r9, rsi 00075 4d 8d b7 08 06 00 00 lea r14, QWORD PTR [r15+1544] 0007c 42 88 b4 38 00 05 00 00 mov BYTE PTR [rax+r15+1280], sil 00084 41 8d 7a 0e lea edi, QWORD PTR [r10+14] 00088 0f 1f 84 00 00 00 00 00 npad 8 $LL10@stbi__buil: ; 1484 : if (h->size[k] == j) { 00090 49 8d 8f 00 05 00 00 lea rcx, QWORD PTR [r15+1280] 00097 8b c3 mov eax, ebx 00099 2b c2 sub eax, edx 0009b 49 03 c9 add rcx, r9 0009e 41 89 46 48 mov DWORD PTR [r14+72], eax 000a2 0f b6 01 movzx eax, BYTE PTR [rcx] 000a5 41 3b c2 cmp eax, r10d 000a8 75 47 jne SHORT $LN21@stbi__buil ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; 000aa 4d 8d 87 00 02 00 00 lea r8, QWORD PTR [r15+512] 000b1 4f 8d 04 48 lea r8, QWORD PTR [r8+r9*2] 000b5 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL11@stbi__buil: ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); 000c0 66 41 89 10 mov WORD PTR [r8], dx 000c4 48 8d 49 01 lea rcx, QWORD PTR [rcx+1] 000c8 0f b6 01 movzx eax, BYTE PTR [rcx] 000cb 4d 8d 40 02 lea r8, QWORD PTR [r8+2] 000cf 44 8b da mov r11d, edx 000d2 ff c3 inc ebx 000d4 49 ff c1 inc r9 000d7 ff c2 inc edx 000d9 41 3b c2 cmp eax, r10d 000dc 74 e2 je SHORT $LL11@stbi__buil ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); 000de 41 8b ca mov ecx, r10d 000e1 b8 01 00 00 00 mov eax, 1 000e6 d3 e0 shl eax, cl 000e8 44 3b d8 cmp r11d, eax 000eb 0f 83 da 00 00 00 jae $LN35@stbi__buil $LN21@stbi__buil: ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); 000f1 8b cf mov ecx, edi 000f3 8b c2 mov eax, edx 000f5 d3 e0 shl eax, cl ; 1491 : code <<= 1; 000f7 03 d2 add edx, edx 000f9 41 89 06 mov DWORD PTR [r14], eax 000fc 41 ff c2 inc r10d 000ff 49 83 c6 04 add r14, 4 00103 83 ef 01 sub edi, 1 00106 79 88 jns SHORT $LL10@stbi__buil ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; 00108 49 63 c2 movsxd rax, r10d ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); 0010b ba ff 00 00 00 mov edx, 255 ; 000000ffH 00110 41 b8 00 02 00 00 mov r8d, 512 ; 00000200H 00116 49 8b cf mov rcx, r15 00119 41 c7 84 87 04 06 00 00 ff ff ff ff mov DWORD PTR [r15+rax*4+1540], -1 ; ffffffffH 00125 e8 00 00 00 00 call memset ; 1497 : for (i = 0; i < k; ++i) { 0012a 85 db test ebx, ebx 0012c 7e 57 jle SHORT $LN14@stbi__buil 0012e 48 89 6c 24 40 mov QWORD PTR [rsp+64], rbp 00133 49 8d bf 00 05 00 00 lea rdi, QWORD PTR [r15+1280] 0013a 49 8d af 00 02 00 00 lea rbp, QWORD PTR [r15+512] $LL15@stbi__buil: ; 1498 : int s = h->size[i]; 00141 0f b6 07 movzx eax, BYTE PTR [rdi] ; 1499 : if (s <= FAST_BITS) { 00144 83 f8 09 cmp eax, 9 00147 77 2a ja SHORT $LN13@stbi__buil ; 1500 : int c = h->code[i] << (FAST_BITS - s); 00149 0f b7 55 00 movzx edx, WORD PTR [rbp] 0014d b9 09 00 00 00 mov ecx, 9 00152 2b c8 sub ecx, eax ; 1501 : int m = 1 << (FAST_BITS - s); 00154 b8 01 00 00 00 mov eax, 1 00159 d3 e0 shl eax, cl 0015b d3 e2 shl edx, cl ; 1502 : for (j = 0; j < m; ++j) { 0015d 85 c0 test eax, eax 0015f 7e 12 jle SHORT $LN13@stbi__buil ; 1503 : h->fast[c + j] = (stbi_uc)i; 00161 48 63 ca movsxd rcx, edx 00164 40 0f b6 d6 movzx edx, sil 00168 49 03 cf add rcx, r15 0016b 4c 63 c0 movsxd r8, eax 0016e e8 00 00 00 00 call memset $LN13@stbi__buil: ; 1497 : for (i = 0; i < k; ++i) { 00173 ff c6 inc esi 00175 48 83 c5 02 add rbp, 2 00179 48 ff c7 inc rdi 0017c 3b f3 cmp esi, ebx 0017e 7c c1 jl SHORT $LL15@stbi__buil 00180 48 8b 6c 24 40 mov rbp, QWORD PTR [rsp+64] $LN14@stbi__buil: ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; 00185 b8 01 00 00 00 mov eax, 1 $LN68@stbi__buil: 0018a 48 8b 7c 24 48 mov rdi, QWORD PTR [rsp+72] 0018f 4c 8b 74 24 50 mov r14, QWORD PTR [rsp+80] ; 1508 : } 00194 48 83 c4 20 add rsp, 32 ; 00000020H 00198 41 5f pop r15 0019a 5e pop rsi 0019b 5b pop rbx 0019c c3 ret 0 $LN34@stbi__buil: ; 431 : stbi__g_failure_reason = str; 0019d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001a3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001ac b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 001b1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001b5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@DEFOLMLB@bad?5size?5list@ 001bc 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); 001c0 33 c0 xor eax, eax ; 1508 : } 001c2 48 83 c4 20 add rsp, 32 ; 00000020H 001c6 41 5f pop r15 001c8 5e pop rsi 001c9 5b pop rbx 001ca c3 ret 0 $LN35@stbi__buil: ; 431 : stbi__g_failure_reason = str; 001cb 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001d1 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001da b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 001df 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001e3 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@FOKGPEKG@bad?5code?5lengths@ 001ea 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); 001ee 33 c0 xor eax, eax 001f0 eb 98 jmp SHORT $LN68@stbi__buil stbi__build_huffman ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__build_fast_ac _TEXT SEGMENT fast_ac$ = 16 h$ = 24 stbi__build_fast_ac PROC ; COMDAT ; 1513 : { 00000 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 00005 56 push rsi ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { 00006 33 ed xor ebp, ebp 00008 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 0000d 44 8b d5 mov r10d, ebp 00010 48 89 7c 24 18 mov QWORD PTR [rsp+24], rdi 00015 48 8b f2 mov rsi, rdx 00018 4c 8b c9 mov r9, rcx 0001b 4c 8b da mov r11, rdx 0001e 66 90 npad 2 $LL4@stbi__buil: ; 1516 : stbi_uc fast = h->fast[i]; 00020 41 0f b6 03 movzx eax, BYTE PTR [r11] ; 1517 : fast_ac[i] = 0; 00024 66 41 89 29 mov WORD PTR [r9], bp ; 1518 : if (fast < 255) { 00028 3c ff cmp al, 255 ; 000000ffH 0002a 0f 83 82 00 00 00 jae $LN2@stbi__buil ; 1519 : int rs = h->values[fast]; 00030 44 0f b6 84 30 00 04 00 00 movzx r8d, BYTE PTR [rax+rsi+1024] ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; 00039 0f b6 9c 30 00 05 00 00 movzx ebx, BYTE PTR [rax+rsi+1280] 00041 41 8b f8 mov edi, r8d 00044 c1 ef 04 shr edi, 4 00047 41 83 e0 0f and r8d, 15 ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { 0004b 74 65 je SHORT $LN2@stbi__buil 0004d 42 8d 04 03 lea eax, DWORD PTR [rbx+r8] 00051 83 f8 09 cmp eax, 9 00054 77 5c ja SHORT $LN2@stbi__buil ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); 00056 8b cb mov ecx, ebx 00058 41 8b c2 mov eax, r10d 0005b d3 e0 shl eax, cl ; 1527 : int m = 1 << (magbits - 1); 0005d ba 01 00 00 00 mov edx, 1 00062 25 ff 01 00 00 and eax, 511 ; 000001ffH 00067 b9 09 00 00 00 mov ecx, 9 0006c 41 2b c8 sub ecx, r8d 0006f d3 f8 sar eax, cl 00071 41 8d 48 ff lea ecx, DWORD PTR [r8-1] 00075 d3 e2 shl edx, cl ; 1528 : if (k < m) k += (~0U << magbits) + 1; 00077 3b c2 cmp eax, edx 00079 7d 13 jge SHORT $LN7@stbi__buil 0007b 41 8b c8 mov ecx, r8d 0007e ba 01 00 00 00 mov edx, 1 00083 d3 e2 shl edx, cl 00085 b9 01 00 00 00 mov ecx, 1 0008a 2b ca sub ecx, edx 0008c 03 c1 add eax, ecx $LN7@stbi__buil: ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) 0008e 8d 88 80 00 00 00 lea ecx, DWORD PTR [rax+128] 00094 81 f9 ff 00 00 00 cmp ecx, 255 ; 000000ffH 0009a 77 16 ja SHORT $LN2@stbi__buil ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); 0009c 66 c1 e0 04 shl ax, 4 000a0 66 03 c7 add ax, di 000a3 66 c1 e0 04 shl ax, 4 000a7 66 03 c3 add ax, bx 000aa 66 41 03 c0 add ax, r8w 000ae 66 41 89 01 mov WORD PTR [r9], ax $LN2@stbi__buil: ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { 000b2 41 ff c2 inc r10d 000b5 49 ff c3 inc r11 000b8 49 83 c1 02 add r9, 2 000bc 41 81 fa 00 02 00 00 cmp r10d, 512 ; 00000200H 000c3 0f 8c 57 ff ff ff jl $LL4@stbi__buil 000c9 48 8b 7c 24 18 mov rdi, QWORD PTR [rsp+24] 000ce 48 8b 5c 24 10 mov rbx, QWORD PTR [rsp+16] ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } 000d3 48 8b 6c 24 20 mov rbp, QWORD PTR [rsp+32] 000d8 5e pop rsi 000d9 c3 ret 0 stbi__build_fast_ac ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__grow_buffer_unsafe _TEXT SEGMENT j$ = 48 stbi__grow_buffer_unsafe PROC ; COMDAT ; 1538 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 8b f9 mov rdi, rcx 0000d 48 89 74 24 30 mov QWORD PTR [rsp+48], rsi $LL4@stbi__grow: ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); 00012 83 bf 2c 48 00 00 00 cmp DWORD PTR [rdi+18476], 0 00019 74 07 je SHORT $LN10@stbi__grow 0001b 33 f6 xor esi, esi 0001d e9 04 01 00 00 jmp $LN8@stbi__grow $LN10@stbi__grow: 00022 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00025 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0002c 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00033 73 0f jae SHORT $LN13@stbi__grow ; 1078 : return *s->img_buffer++; 00035 0f b6 08 movzx ecx, BYTE PTR [rax] 00038 48 ff c0 inc rax 0003b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00042 eb 26 jmp SHORT $LN12@stbi__grow $LN13@stbi__grow: ; 1079 : if (s->read_from_callbacks) { 00044 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00048 74 1e je SHORT $LN14@stbi__grow ; 1080 : stbi__refill_buffer(s); 0004a 48 8b cb mov rcx, rbx 0004d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00052 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00059 0f b6 08 movzx ecx, BYTE PTR [rax] 0005c 48 ff c0 inc rax 0005f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00066 eb 02 jmp SHORT $LN12@stbi__grow $LN14@stbi__grow: ; 1082 : } ; 1083 : return 0; 00068 32 c9 xor cl, cl $LN12@stbi__grow: ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); 0006a 0f b6 f1 movzx esi, cl ; 1541 : if (b == 0xff) { 0006d 81 fe ff 00 00 00 cmp esi, 255 ; 000000ffH 00073 0f 85 ad 00 00 00 jne $LN8@stbi__grow ; 1542 : int c = stbi__get8(j->s); 00079 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0007c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00083 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0008a 73 0f jae SHORT $LN17@stbi__grow ; 1078 : return *s->img_buffer++; 0008c 0f b6 08 movzx ecx, BYTE PTR [rax] 0008f 48 ff c0 inc rax 00092 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00099 eb 26 jmp SHORT $LN16@stbi__grow $LN17@stbi__grow: ; 1079 : if (s->read_from_callbacks) { 0009b 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0009f 74 1e je SHORT $LN18@stbi__grow ; 1080 : stbi__refill_buffer(s); 000a1 48 8b cb mov rcx, rbx 000a4 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000a9 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000b0 0f b6 08 movzx ecx, BYTE PTR [rax] 000b3 48 ff c0 inc rax 000b6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000bd eb 02 jmp SHORT $LN16@stbi__grow $LN18@stbi__grow: ; 1082 : } ; 1083 : return 0; 000bf 32 c9 xor cl, cl $LN16@stbi__grow: ; 1542 : int c = stbi__get8(j->s); 000c1 0f b6 c1 movzx eax, cl ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes 000c4 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 000c9 75 57 jne SHORT $LN6@stbi__grow 000cb 0f 1f 44 00 00 npad 5 $LL5@stbi__grow: 000d0 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 000d3 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000da 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000e1 73 0f jae SHORT $LN21@stbi__grow ; 1078 : return *s->img_buffer++; 000e3 0f b6 08 movzx ecx, BYTE PTR [rax] 000e6 48 ff c0 inc rax 000e9 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000f0 eb 26 jmp SHORT $LN20@stbi__grow $LN21@stbi__grow: ; 1079 : if (s->read_from_callbacks) { 000f2 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000f6 74 1e je SHORT $LN22@stbi__grow ; 1080 : stbi__refill_buffer(s); 000f8 48 8b cb mov rcx, rbx 000fb e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00100 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00107 0f b6 08 movzx ecx, BYTE PTR [rax] 0010a 48 ff c0 inc rax 0010d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00114 eb 02 jmp SHORT $LN20@stbi__grow $LN22@stbi__grow: ; 1082 : } ; 1083 : return 0; 00116 32 c9 xor cl, cl $LN20@stbi__grow: ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes 00118 0f b6 c1 movzx eax, cl 0011b 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00120 74 ae je SHORT $LL5@stbi__grow $LN6@stbi__grow: ; 1544 : if (c != 0) { 00122 85 c0 test eax, eax 00124 75 37 jne SHORT $LN26@stbi__grow $LN8@stbi__grow: ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); 00126 8b 87 24 48 00 00 mov eax, DWORD PTR [rdi+18468] 0012c b9 18 00 00 00 mov ecx, 24 00131 2b c8 sub ecx, eax ; 1551 : j->code_bits += 8; 00133 83 c0 08 add eax, 8 00136 d3 e6 shl esi, cl 00138 09 b7 20 48 00 00 or DWORD PTR [rdi+18464], esi 0013e 89 87 24 48 00 00 mov DWORD PTR [rdi+18468], eax ; 1552 : } while (j->code_bits <= 24); 00144 83 f8 18 cmp eax, 24 00147 0f 8e c5 fe ff ff jle $LL4@stbi__grow 0014d 48 8b 74 24 30 mov rsi, QWORD PTR [rsp+48] ; 1553 : } 00152 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 00157 48 83 c4 20 add rsp, 32 ; 00000020H 0015b 5f pop rdi 0015c c3 ret 0 $LN26@stbi__grow: 0015d 48 8b 74 24 30 mov rsi, QWORD PTR [rsp+48] 00162 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 00167 88 87 28 48 00 00 mov BYTE PTR [rdi+18472], al 0016d c7 87 2c 48 00 00 01 00 00 00 mov DWORD PTR [rdi+18476], 1 00177 48 83 c4 20 add rsp, 32 ; 00000020H 0017b 5f pop rdi 0017c c3 ret 0 stbi__grow_buffer_unsafe ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_huff_decode _TEXT SEGMENT j$ = 48 h$ = 56 stbi__jpeg_huff_decode PROC ; COMDAT ; 1560 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 0000a 83 b9 24 48 00 00 10 cmp DWORD PTR [rcx+18468], 16 00011 48 8b fa mov rdi, rdx 00014 48 8b d9 mov rbx, rcx 00017 7d 05 jge SHORT $LN5@stbi__jpeg 00019 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN5@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 0001e 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] 00025 41 8b c1 mov eax, r9d 00028 48 c1 e8 17 shr rax, 23 ; 1569 : k = h->fast[c]; 0002c 0f b6 0c 38 movzx ecx, BYTE PTR [rax+rdi] ; 1570 : if (k < 255) { 00030 80 f9 ff cmp cl, 255 ; 000000ffH 00033 73 39 jae SHORT $LN6@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 00035 8b 83 24 48 00 00 mov eax, DWORD PTR [rbx+18468] 0003b 8b d1 mov edx, ecx 0003d 0f b6 8c 39 00 05 00 00 movzx ecx, BYTE PTR [rcx+rdi+1280] 00045 3b c8 cmp ecx, eax 00047 7f 5e jg SHORT $LN12@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 00049 41 d3 e1 shl r9d, cl ; 1575 : j->code_bits -= s; 0004c 2b c1 sub eax, ecx 0004e 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d 00055 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax ; 1576 : return h->values[k]; 0005b 0f b6 84 3a 00 04 00 00 movzx eax, BYTE PTR [rdx+rdi+1024] ; 1608 : } 00063 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00068 48 83 c4 20 add rsp, 32 ; 00000020H 0006c 5f pop rdi 0006d c3 ret 0 $LN6@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 0006e 41 8b c9 mov ecx, r9d ; 1587 : if (temp < h->maxcode[k]) 00071 48 8d 87 2c 06 00 00 lea rax, QWORD PTR [rdi+1580] 00078 c1 e9 10 shr ecx, 16 0007b 41 b8 0a 00 00 00 mov r8d, 10 00081 3b 08 cmp ecx, DWORD PTR [rax] 00083 72 0b jb SHORT $LN16@stbi__jpeg $LL4@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 00085 41 ff c0 inc r8d 00088 48 8d 40 04 lea rax, QWORD PTR [rax+4] ; 1587 : if (temp < h->maxcode[k]) 0008c 3b 08 cmp ecx, DWORD PTR [rax] 0008e 73 f5 jae SHORT $LL4@stbi__jpeg $LN16@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 00090 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00097 41 83 f8 11 cmp r8d, 17 0009b 75 1a jne SHORT $LN9@stbi__jpeg ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; 0009d 41 8d 42 f0 lea eax, DWORD PTR [r10-16] 000a1 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax $LN12@stbi__jpeg: ; 1608 : } 000a7 b8 ff ff ff ff mov eax, -1 000ac 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000b1 48 83 c4 20 add rsp, 32 ; 00000020H 000b5 5f pop rdi 000b6 c3 ret 0 $LN9@stbi__jpeg: ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) 000b7 45 3b c2 cmp r8d, r10d 000ba 7f eb jg SHORT $LN12@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 000bc b9 20 00 00 00 mov ecx, 32 ; 00000020H 000c1 49 63 c0 movsxd rax, r8d 000c4 41 2b c8 sub ecx, r8d 000c7 45 8b d9 mov r11d, r9d 000ca 41 d3 eb shr r11d, cl 000cd 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__bmask 000d4 44 23 1c 81 and r11d, DWORD PTR [rcx+rax*4] 000d8 44 03 9c 87 4c 06 00 00 add r11d, DWORD PTR [rdi+rax*4+1612] ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 000e0 41 81 fb ff 00 00 00 cmp r11d, 255 ; 000000ffH 000e7 77 be ja SHORT $LN12@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 000e9 45 2b d0 sub r10d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 000ec 49 63 c3 movsxd rax, r11d 000ef 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 000f6 41 8b c8 mov ecx, r8d 000f9 41 d3 e1 shl r9d, cl 000fc 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d 00103 0f b6 84 38 00 04 00 00 movzx eax, BYTE PTR [rax+rdi+1024] ; 1608 : } 0010b 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00110 48 83 c4 20 add rsp, 32 ; 00000020H 00114 5f pop rdi 00115 c3 ret 0 stbi__jpeg_huff_decode ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__extend_receive _TEXT SEGMENT j$ = 48 n$ = 56 stbi__extend_receive PROC ; COMDAT ; 1616 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 63 fa movsxd rdi, edx 0000d 48 8b d9 mov rbx, rcx ; 1617 : unsigned int k; ; 1618 : int sgn; ; 1619 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 00010 39 b9 24 48 00 00 cmp DWORD PTR [rcx+18468], edi 00016 7d 05 jge SHORT $LN2@stbi__exte 00018 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN2@stbi__exte: ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 0001d 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00024 44 3b d7 cmp r10d, edi 00027 7d 0d jge SHORT $LN3@stbi__exte 00029 33 c0 xor eax, eax ; 1628 : } 0002b 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00030 48 83 c4 20 add rsp, 32 ; 00000020H 00034 5f pop rdi 00035 c3 ret 0 $LN3@stbi__exte: ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) 00036 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; 0003d 4c 8d 1d 00 00 00 00 lea r11, OFFSET FLAT:__ImageBase 00044 45 8b c1 mov r8d, r9d 00047 8b cf mov ecx, edi 00049 41 d3 c0 rol r8d, cl ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; 0004c 44 2b d7 sub r10d, edi 0004f 48 8d 0c bd 00 00 00 00 lea rcx, QWORD PTR [rdi*4] 00057 41 c1 e9 1f shr r9d, 31 0005b 42 8b 94 19 00 00 00 00 mov edx, DWORD PTR stbi__bmask[rcx+r11] ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); 00063 41 ff c9 dec r9d 00066 8b c2 mov eax, edx 00068 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 0006f f7 d0 not eax 00071 41 23 d0 and edx, r8d 00074 41 23 c0 and eax, r8d 00077 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax 0007d 42 8b 84 19 00 00 00 00 mov eax, DWORD PTR stbi__jbias[rcx+r11] ; 1628 : } 00085 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0008a 41 23 c1 and eax, r9d 0008d 03 c2 add eax, edx 0008f 48 83 c4 20 add rsp, 32 ; 00000020H 00093 5f pop rdi 00094 c3 ret 0 stbi__extend_receive ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_get_bits _TEXT SEGMENT j$ = 48 n$ = 56 stbi__jpeg_get_bits PROC ; COMDAT ; 1632 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 63 fa movsxd rdi, edx 0000d 48 8b d9 mov rbx, rcx ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 00010 39 b9 24 48 00 00 cmp DWORD PTR [rcx+18468], edi 00016 7d 05 jge SHORT $LN2@stbi__jpeg 00018 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN2@stbi__jpeg: ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 0001d 44 8b 83 24 48 00 00 mov r8d, DWORD PTR [rbx+18468] 00024 44 3b c7 cmp r8d, edi 00027 7d 0d jge SHORT $LN3@stbi__jpeg 00029 33 c0 xor eax, eax ; 1640 : return k; ; 1641 : } 0002b 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00030 48 83 c4 20 add rsp, 32 ; 00000020H 00034 5f pop rdi 00035 c3 ret 0 $LN3@stbi__jpeg: ; 1636 : k = stbi_lrot(j->code_buffer, n); 00036 8b 93 20 48 00 00 mov edx, DWORD PTR [rbx+18464] 0003c 8b cf mov ecx, edi 0003e d3 c2 rol edx, cl ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; 00040 44 2b c7 sub r8d, edi 00043 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:stbi__bmask 0004a 44 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], r8d 00051 8b 04 b9 mov eax, DWORD PTR [rcx+rdi*4] 00054 8b c8 mov ecx, eax 00056 f7 d1 not ecx 00058 23 ca and ecx, edx 0005a 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], ecx 00060 23 c2 and eax, edx ; 1640 : return k; ; 1641 : } 00062 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00067 48 83 c4 20 add rsp, 32 ; 00000020H 0006b 5f pop rdi 0006c c3 ret 0 stbi__jpeg_get_bits ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_get_bit _TEXT SEGMENT j$ = 48 stbi__jpeg_get_bit PROC ; COMDAT ; 1644 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); 00006 83 b9 24 48 00 00 01 cmp DWORD PTR [rcx+18468], 1 0000d 48 8b d9 mov rbx, rcx 00010 7d 05 jge SHORT $LN2@stbi__jpeg 00012 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN2@stbi__jpeg: ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing 00017 8b 93 24 48 00 00 mov edx, DWORD PTR [rbx+18468] 0001d 83 fa 01 cmp edx, 1 00020 7d 08 jge SHORT $LN3@stbi__jpeg 00022 33 c0 xor eax, eax ; 1652 : } 00024 48 83 c4 20 add rsp, 32 ; 00000020H 00028 5b pop rbx 00029 c3 ret 0 $LN3@stbi__jpeg: ; 1648 : k = j->code_buffer; 0002a 8b 83 20 48 00 00 mov eax, DWORD PTR [rbx+18464] ; 1649 : j->code_buffer <<= 1; 00030 8d 0c 00 lea ecx, DWORD PTR [rax+rax] ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; 00033 25 00 00 00 80 and eax, -2147483648 ; 80000000H 00038 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], ecx 0003e 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00041 89 8b 24 48 00 00 mov DWORD PTR [rbx+18468], ecx ; 1652 : } 00047 48 83 c4 20 add rsp, 32 ; 00000020H 0004b 5b pop rbx 0004c c3 ret 0 stbi__jpeg_get_bit ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_decode_block _TEXT SEGMENT j$ = 80 data$ = 88 hdc$ = 96 hac$ = 104 fac$ = 112 b$ = 120 dequant$ = 128 stbi__jpeg_decode_block PROC ; COMDAT ; 1673 : { 00000 40 53 push rbx 00002 55 push rbp 00003 57 push rdi 00004 41 56 push r14 00006 41 57 push r15 00008 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 0000c 83 b9 24 48 00 00 10 cmp DWORD PTR [rcx+18468], 16 00013 4d 8b f1 mov r14, r9 00016 49 8b f8 mov rdi, r8 00019 4c 8b fa mov r15, rdx 0001c 48 8b d9 mov rbx, rcx 0001f 7d 05 jge SHORT $LN5@stbi__jpeg 00021 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN5@stbi__jpeg: ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 00026 83 bb 24 48 00 00 10 cmp DWORD PTR [rbx+18468], 16 0002d 7d 08 jge SHORT $LN25@stbi__jpeg 0002f 48 8b cb mov rcx, rbx 00032 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN25@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 00037 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1570 : if (k < 255) { 0003e 48 8d 2d 00 00 00 00 lea rbp, OFFSET FLAT:__ImageBase 00045 41 8b c1 mov eax, r9d 00048 48 c1 e8 17 shr rax, 23 0004c 0f b6 0c 38 movzx ecx, BYTE PTR [rax+rdi] 00050 80 f9 ff cmp cl, 255 ; 000000ffH 00053 73 33 jae SHORT $LN26@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 00055 8b 83 24 48 00 00 mov eax, DWORD PTR [rbx+18468] 0005b 8b d1 mov edx, ecx 0005d 0f b6 8c 39 00 05 00 00 movzx ecx, BYTE PTR [rcx+rdi+1280] 00065 3b c8 cmp ecx, eax 00067 7f 59 jg SHORT $LN7@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 00069 41 d3 e1 shl r9d, cl ; 1575 : j->code_bits -= s; 0006c 2b c1 sub eax, ecx 0006e 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d 00075 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax ; 1576 : return h->values[k]; 0007b 0f b6 84 3a 00 04 00 00 movzx eax, BYTE PTR [rdx+rdi+1024] 00083 e9 bc 00 00 00 jmp $LN21@stbi__jpeg $LN26@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 00088 41 8b c9 mov ecx, r9d ; 1587 : if (temp < h->maxcode[k]) 0008b 48 8d 87 2c 06 00 00 lea rax, QWORD PTR [rdi+1580] 00092 c1 e9 10 shr ecx, 16 00095 41 b8 0a 00 00 00 mov r8d, 10 0009b 3b 08 cmp ecx, DWORD PTR [rax] 0009d 72 0c jb SHORT $LN80@stbi__jpeg 0009f 90 npad 1 $LL24@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 000a0 41 ff c0 inc r8d 000a3 48 8d 40 04 lea rax, QWORD PTR [rax+4] ; 1587 : if (temp < h->maxcode[k]) 000a7 3b 08 cmp ecx, DWORD PTR [rax] 000a9 73 f5 jae SHORT $LL24@stbi__jpeg $LN80@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 000ab 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 000b2 41 83 f8 11 cmp r8d, 17 000b6 75 3b jne SHORT $LN29@stbi__jpeg ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; 000b8 41 8d 42 f0 lea eax, DWORD PTR [r10-16] 000bc 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax $LN7@stbi__jpeg: ; 431 : stbi__g_failure_reason = str; 000c2 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000c8 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000d1 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000d6 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000da 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@IIMLINA@bad?5huffman?5code@ 000e1 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); 000e5 33 c0 xor eax, eax ; 1727 : } 000e7 48 83 c4 20 add rsp, 32 ; 00000020H 000eb 41 5f pop r15 000ed 41 5e pop r14 000ef 5f pop rdi 000f0 5d pop rbp 000f1 5b pop rbx 000f2 c3 ret 0 $LN29@stbi__jpeg: ; 1595 : if (k > j->code_bits) 000f3 45 3b c2 cmp r8d, r10d 000f6 7f ca jg SHORT $LN7@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 000f8 49 63 c0 movsxd rax, r8d 000fb b9 20 00 00 00 mov ecx, 32 ; 00000020H 00100 41 2b c8 sub ecx, r8d 00103 45 8b d9 mov r11d, r9d 00106 41 d3 eb shr r11d, cl 00109 44 23 9c 85 00 00 00 00 and r11d, DWORD PTR stbi__bmask[rbp+rax*4] 00111 44 03 9c 87 4c 06 00 00 add r11d, DWORD PTR [rdi+rax*4+1612] ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 00119 41 81 fb ff 00 00 00 cmp r11d, 255 ; 000000ffH 00120 77 a0 ja SHORT $LN7@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 00122 45 2b d0 sub r10d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 00125 49 63 c3 movsxd rax, r11d 00128 41 8b c8 mov ecx, r8d 0012b 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 00132 41 d3 e1 shl r9d, cl 00135 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d 0013c 0f b6 84 38 00 04 00 00 movzx eax, BYTE PTR [rax+rdi+1024] $LN21@stbi__jpeg: ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); 00144 0f b6 f8 movzx edi, al 00147 83 ff 0f cmp edi, 15 0014a 0f 87 72 ff ff ff ja $LN7@stbi__jpeg ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); 00150 0f 57 c0 xorps xmm0, xmm0 00153 41 0f 11 07 movups XMMWORD PTR [r15], xmm0 00157 41 0f 11 47 10 movups XMMWORD PTR [r15+16], xmm0 0015c 41 0f 11 47 20 movups XMMWORD PTR [r15+32], xmm0 00161 41 0f 11 47 30 movups XMMWORD PTR [r15+48], xmm0 00166 41 0f 11 47 40 movups XMMWORD PTR [r15+64], xmm0 0016b 41 0f 11 47 50 movups XMMWORD PTR [r15+80], xmm0 00170 41 0f 11 47 60 movups XMMWORD PTR [r15+96], xmm0 00175 41 0f 11 47 70 movups XMMWORD PTR [r15+112], xmm0 ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; 0017a 84 c0 test al, al 0017c 74 68 je SHORT $LN19@stbi__jpeg ; 1619 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 0017e 39 bb 24 48 00 00 cmp DWORD PTR [rbx+18468], edi 00184 7d 08 jge SHORT $LN37@stbi__jpeg 00186 48 8b cb mov rcx, rbx 00189 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN37@stbi__jpeg: ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 0018e 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00195 44 3b d7 cmp r10d, edi 00198 7c 4c jl SHORT $LN19@stbi__jpeg ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) 0019a 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1623 : k = stbi_lrot(j->code_buffer, n); 001a1 8b cf mov ecx, edi 001a3 45 8b c1 mov r8d, r9d ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; 001a6 44 2b d7 sub r10d, edi 001a9 41 d3 c0 rol r8d, cl 001ac 48 8d 0c bd 00 00 00 00 lea rcx, QWORD PTR [rdi*4] 001b4 8b 94 29 00 00 00 00 mov edx, DWORD PTR stbi__bmask[rcx+rbp] 001bb 8b c2 mov eax, edx 001bd 41 c1 e9 1f shr r9d, 31 001c1 f7 d0 not eax ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); 001c3 41 ff c9 dec r9d 001c6 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 001cd 44 23 8c 29 00 00 00 00 and r9d, DWORD PTR stbi__jbias[rcx+rbp] 001d5 41 23 c0 and eax, r8d 001d8 41 23 d0 and edx, r8d 001db 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax 001e1 44 03 ca add r9d, edx ; 1628 : } 001e4 eb 03 jmp SHORT $LN20@stbi__jpeg $LN19@stbi__jpeg: ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 001e6 45 33 c9 xor r9d, r9d $LN20@stbi__jpeg: 001e9 48 63 44 24 78 movsxd rax, DWORD PTR b$[rsp] 001ee 4c 8d 04 40 lea r8, QWORD PTR [rax+rax*2] ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 001f2 41 8b c1 mov eax, r9d ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 001f5 49 c1 e0 05 shl r8, 5 ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 001f9 f7 d0 not eax ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 001fb 41 8b 94 18 b8 46 00 00 mov edx, DWORD PTR [r8+rbx+18104] ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 00203 8b ca mov ecx, edx 00205 f7 d1 not ecx 00207 33 c8 xor ecx, eax 00209 78 5e js SHORT $LN8@stbi__jpeg ; 524 : if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. 0020b 85 d2 test edx, edx 0020d 79 16 jns SHORT $LN42@stbi__jpeg 0020f 45 85 c9 test r9d, r9d 00212 79 11 jns SHORT $LN42@stbi__jpeg 00214 33 c9 xor ecx, ecx 00216 b8 00 00 00 80 mov eax, -2147483648 ; ffffffff80000000H 0021b 41 2b c1 sub eax, r9d 0021e 3b d0 cmp edx, eax 00220 0f 9d c1 setge cl 00223 eb 0f jmp SHORT $LN40@stbi__jpeg $LN42@stbi__jpeg: ; 525 : return a <= INT_MAX - b; 00225 33 c9 xor ecx, ecx 00227 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0022c 41 2b c1 sub eax, r9d 0022f 3b d0 cmp edx, eax 00231 0f 9e c1 setle cl $LN40@stbi__jpeg: ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00234 85 c9 test ecx, ecx 00236 75 31 jne SHORT $LN8@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 00238 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0023e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00247 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0024c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00250 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09IFDKCGFO@bad?5delta@ 00257 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 0025b 33 c0 xor eax, eax ; 1727 : } 0025d 48 83 c4 20 add rsp, 32 ; 00000020H 00261 41 5f pop r15 00263 41 5e pop r14 00265 5f pop rdi 00266 5d pop rbp 00267 5b pop rbx 00268 c3 ret 0 $LN8@stbi__jpeg: 00269 4c 89 64 24 58 mov QWORD PTR [rsp+88], r12 ; 1686 : dc = j->img_comp[b].dc_pred + diff; 0026e 42 8d 0c 0a lea ecx, DWORD PTR [rdx+r9] ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00272 4c 8b a4 24 80 00 00 00 mov r12, QWORD PTR dequant$[rsp] 0027a 41 89 8c 18 b8 46 00 00 mov DWORD PTR [r8+rbx+18104], ecx 00282 45 0f bf 04 24 movsx r8d, WORD PTR [r12] ; 531 : if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow 00287 41 8d 40 01 lea eax, DWORD PTR [r8+1] 0028b 66 83 f8 01 cmp ax, 1 0028f 0f 86 81 00 00 00 jbe $LN48@stbi__jpeg ; 532 : if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid 00295 0f b7 c1 movzx eax, cx 00298 44 0f bf c9 movsx r9d, cx 0029c 66 41 33 c0 xor ax, r8w 002a0 45 8b d0 mov r10d, r8d 002a3 66 0f ba e0 0f bt ax, 15 002a8 72 13 jb SHORT $LN49@stbi__jpeg 002aa b8 ff 7f 00 00 mov eax, 32767 ; 00007fffH 002af 99 cdq 002b0 41 f7 fa idiv r10d 002b3 33 d2 xor edx, edx 002b5 44 3b c8 cmp r9d, eax 002b8 0f 9e c2 setle dl 002bb eb 1f jmp SHORT $LN46@stbi__jpeg $LN49@stbi__jpeg: ; 533 : if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN 002bd b8 00 80 ff ff mov eax, -32768 ; ffffffffffff8000H 002c2 99 cdq 002c3 41 f7 fa idiv r10d 002c6 33 d2 xor edx, edx 002c8 66 45 85 c0 test r8w, r8w 002cc 79 08 jns SHORT $LN50@stbi__jpeg 002ce 44 3b c8 cmp r9d, eax 002d1 0f 9e c2 setle dl 002d4 eb 06 jmp SHORT $LN46@stbi__jpeg $LN50@stbi__jpeg: ; 534 : return a >= SHRT_MIN / b; 002d6 44 3b c8 cmp r9d, eax 002d9 0f 9d c2 setge dl $LN46@stbi__jpeg: ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 002dc 85 d2 test edx, edx 002de 75 36 jne SHORT $LN48@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 002e0 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 002e6 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 002ef 4c 8b 64 24 58 mov r12, QWORD PTR [rsp+88] 002f4 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 002f9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 002fd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ 00304 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00308 33 c0 xor eax, eax ; 1727 : } 0030a 48 83 c4 20 add rsp, 32 ; 00000020H 0030e 41 5f pop r15 00310 41 5e pop r14 00312 5f pop rdi 00313 5d pop rbp 00314 5b pop rbx 00315 c3 ret 0 $LN48@stbi__jpeg: 00316 4c 89 6c 24 60 mov QWORD PTR [rsp+96], r13 ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; 0031b bf 01 00 00 00 mov edi, 1 00320 4c 8b 6c 24 70 mov r13, QWORD PTR fac$[rsp] 00325 0f bf c9 movsx ecx, cx 00328 41 0f af c8 imul ecx, r8d 0032c 48 89 74 24 50 mov QWORD PTR [rsp+80], rsi 00331 66 41 89 0f mov WORD PTR [r15], cx $LL4@stbi__jpeg: ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 00335 83 bb 24 48 00 00 10 cmp DWORD PTR [rbx+18468], 16 0033c 7d 08 jge SHORT $LN10@stbi__jpeg 0033e 48 8b cb mov rcx, rbx 00341 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN10@stbi__jpeg: ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 00346 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1698 : r = fac[c]; 0034d 8b 93 24 48 00 00 mov edx, DWORD PTR [rbx+18468] 00353 41 8b c1 mov eax, r9d 00356 48 c1 e8 17 shr rax, 23 0035a 45 0f bf 44 45 00 movsx r8d, WORD PTR [r13+rax*2] ; 1699 : if (r) { // fast-AC path 00360 45 85 c0 test r8d, r8d 00363 74 48 je SHORT $LN11@stbi__jpeg ; 1700 : k += (r >> 4) & 15; // run 00365 41 8b c0 mov eax, r8d ; 1701 : s = r & 15; // combined length 00368 41 8b c8 mov ecx, r8d 0036b c1 f8 04 sar eax, 4 0036e 83 e1 0f and ecx, 15 00371 83 e0 0f and eax, 15 00374 03 f8 add edi, eax ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); 00376 3b ca cmp ecx, edx 00378 0f 8f f9 01 00 00 jg $LN83@stbi__jpeg ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; 0037e 2b d1 sub edx, ecx ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; 00380 48 63 c7 movsxd rax, edi 00383 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], edx 00389 ff c7 inc edi 0038b 41 d3 e1 shl r9d, cl 0038e 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); 00395 0f b6 94 28 00 00 00 00 movzx edx, BYTE PTR stbi__jpeg_dezigzag[rax+rbp] 0039d 48 03 d2 add rdx, rdx 003a0 41 c1 f8 08 sar r8d, 8 003a4 41 0f bf c0 movsx eax, r8w ; 1708 : } 003a8 e9 8a 01 00 00 jmp $LN137@stbi__jpeg $LN11@stbi__jpeg: ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 003ad 83 fa 10 cmp edx, 16 003b0 7d 08 jge SHORT $LN60@stbi__jpeg 003b2 48 8b cb mov rcx, rbx 003b5 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN60@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 003ba 44 8b 9b 20 48 00 00 mov r11d, DWORD PTR [rbx+18464] 003c1 41 8b c3 mov eax, r11d 003c4 48 c1 e8 17 shr rax, 23 ; 1569 : k = h->fast[c]; 003c8 42 0f b6 0c 30 movzx ecx, BYTE PTR [rax+r14] ; 1570 : if (k < 255) { 003cd 80 f9 ff cmp cl, 255 ; 000000ffH 003d0 73 23 jae SHORT $LN61@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 003d2 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 003d9 8b c1 mov eax, ecx 003db 42 0f b6 8c 31 00 05 00 00 movzx ecx, BYTE PTR [rcx+r14+1280] 003e4 41 3b ca cmp ecx, r10d 003e7 0f 8f 8a 01 00 00 jg $LN83@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 003ed 41 d3 e3 shl r11d, cl ; 1575 : j->code_bits -= s; 003f0 44 2b d1 sub r10d, ecx ; 1576 : return h->values[k]; 003f3 eb 7c jmp SHORT $LN138@stbi__jpeg $LN61@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 003f5 41 8b cb mov ecx, r11d ; 1587 : if (temp < h->maxcode[k]) 003f8 49 8d 86 2c 06 00 00 lea rax, QWORD PTR [r14+1580] 003ff c1 e9 10 shr ecx, 16 00402 41 b8 0a 00 00 00 mov r8d, 10 00408 45 8b c8 mov r9d, r8d 0040b 3b 08 cmp ecx, DWORD PTR [rax] 0040d 72 0f jb SHORT $LN81@stbi__jpeg 0040f 90 npad 1 $LL59@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 00410 41 ff c0 inc r8d 00413 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00417 49 ff c1 inc r9 ; 1587 : if (temp < h->maxcode[k]) 0041a 3b 08 cmp ecx, DWORD PTR [rax] 0041c 73 f2 jae SHORT $LL59@stbi__jpeg $LN81@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 0041e 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00425 41 83 f8 11 cmp r8d, 17 00429 0f 84 3e 01 00 00 je $LN95@stbi__jpeg ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) 0042f 45 3b c2 cmp r8d, r10d 00432 0f 8f 3f 01 00 00 jg $LN83@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 00438 b9 20 00 00 00 mov ecx, 32 ; 00000020H 0043d 41 8b d3 mov edx, r11d 00440 41 2b c8 sub ecx, r8d 00443 d3 ea shr edx, cl 00445 42 23 94 8d 00 00 00 00 and edx, DWORD PTR stbi__bmask[rbp+r9*4] 0044d 47 8b 8c 8e 4c 06 00 00 mov r9d, DWORD PTR [r14+r9*4+1612] 00455 44 03 ca add r9d, edx ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 00458 41 81 f9 ff 00 00 00 cmp r9d, 255 ; 000000ffH 0045f 0f 87 12 01 00 00 ja $LN83@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 00465 45 2b d0 sub r10d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 00468 49 63 c1 movsxd rax, r9d 0046b 41 8b c8 mov ecx, r8d 0046e 41 d3 e3 shl r11d, cl $LN138@stbi__jpeg: ; 1712 : s = rs & 15; 00471 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 00478 44 89 9b 20 48 00 00 mov DWORD PTR [rbx+18464], r11d 0047f 42 0f b6 84 30 00 04 00 00 movzx eax, BYTE PTR [rax+r14+1024] 00488 8b f0 mov esi, eax 0048a 83 e6 0f and esi, 15 ; 1714 : if (s == 0) { 0048d 75 13 jne SHORT $LN15@stbi__jpeg ; 1715 : if (rs != 0xf0) break; // end block 0048f 3d f0 00 00 00 cmp eax, 240 ; 000000f0H 00494 0f 85 b3 00 00 00 jne $LN3@stbi__jpeg ; 1716 : k += 16; 0049a 83 c7 10 add edi, 16 ; 1717 : } 0049d e9 a2 00 00 00 jmp $LN2@stbi__jpeg $LN15@stbi__jpeg: ; 1713 : r = rs >> 4; 004a2 c1 e8 04 shr eax, 4 ; 1718 : else { ; 1719 : k += r; 004a5 03 f8 add edi, eax ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; 004a7 48 63 c7 movsxd rax, edi 004aa ff c7 inc edi 004ac 0f b6 ac 28 00 00 00 00 movzx ebp, BYTE PTR stbi__jpeg_dezigzag[rax+rbp] ; 1619 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 004b4 44 3b d6 cmp r10d, esi 004b7 7d 08 jge SHORT $LN72@stbi__jpeg 004b9 48 8b cb mov rcx, rbx 004bc e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN72@stbi__jpeg: ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 004c1 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 004c8 44 3b d6 cmp r10d, esi 004cb 7d 05 jge SHORT $LN73@stbi__jpeg 004cd 45 33 c9 xor r9d, r9d 004d0 eb 52 jmp SHORT $LN71@stbi__jpeg $LN73@stbi__jpeg: ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) 004d2 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; 004d9 4c 8d 1d 00 00 00 00 lea r11, OFFSET FLAT:__ImageBase 004e0 45 8b c1 mov r8d, r9d 004e3 8b ce mov ecx, esi 004e5 41 d3 c0 rol r8d, cl ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; 004e8 44 2b d6 sub r10d, esi 004eb 41 c1 e9 1f shr r9d, 31 004ef 48 8d 0c b5 00 00 00 00 lea rcx, QWORD PTR [rsi*4] 004f7 42 8b 94 19 00 00 00 00 mov edx, DWORD PTR stbi__bmask[rcx+r11] ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); 004ff 41 ff c9 dec r9d 00502 46 23 8c 19 00 00 00 00 and r9d, DWORD PTR stbi__jbias[rcx+r11] 0050a 8b c2 mov eax, edx 0050c f7 d0 not eax 0050e 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 00515 41 23 c0 and eax, r8d 00518 41 23 d0 and edx, r8d 0051b 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax 00521 44 03 ca add r9d, edx $LN71@stbi__jpeg: ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); 00524 48 8d 14 6d 00 00 00 00 lea rdx, QWORD PTR [rbp*2] 0052c 41 0f bf c1 movsx eax, r9w 00530 48 8d 2d 00 00 00 00 lea rbp, OFFSET FLAT:__ImageBase $LN137@stbi__jpeg: ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); 00537 42 0f bf 0c 22 movsx ecx, WORD PTR [rdx+r12] 0053c 0f af c8 imul ecx, eax 0053f 66 42 89 0c 3a mov WORD PTR [rdx+r15], cx $LN2@stbi__jpeg: 00544 83 ff 40 cmp edi, 64 ; 00000040H 00547 0f 8c e8 fd ff ff jl $LL4@stbi__jpeg $LN3@stbi__jpeg: ; 1726 : return 1; 0054d b8 01 00 00 00 mov eax, 1 $LN136@stbi__jpeg: 00552 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 00557 4c 8b 6c 24 60 mov r13, QWORD PTR [rsp+96] 0055c 4c 8b 64 24 58 mov r12, QWORD PTR [rsp+88] ; 1727 : } 00561 48 83 c4 20 add rsp, 32 ; 00000020H 00565 41 5f pop r15 00567 41 5e pop r14 00569 5f pop rdi 0056a 5d pop rbp 0056b 5b pop rbx 0056c c3 ret 0 $LN95@stbi__jpeg: ; 1591 : j->code_bits -= 16; 0056d 41 8d 42 f0 lea eax, DWORD PTR [r10-16] 00571 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax $LN83@stbi__jpeg: ; 431 : stbi__g_failure_reason = str; 00577 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0057d 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00586 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0058b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0058f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@IIMLINA@bad?5huffman?5code@ 00596 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); 0059a 33 c0 xor eax, eax 0059c eb b4 jmp SHORT $LN136@stbi__jpeg stbi__jpeg_decode_block ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_decode_block_prog_dc _TEXT SEGMENT j$ = 64 data$ = 72 hdc$ = 80 b$ = 88 stbi__jpeg_decode_block_prog_dc PROC ; COMDAT ; 1730 : { 00000 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx 00005 56 push rsi 00006 57 push rdi 00007 41 56 push r14 00009 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 0000d 83 b9 38 48 00 00 00 cmp DWORD PTR [rcx+18488], 0 00014 49 8b f8 mov rdi, r8 00017 4d 63 f1 movsxd r14, r9d 0001a 48 8b f2 mov rsi, rdx 0001d 48 8b d9 mov rbx, rcx 00020 74 33 je SHORT $LN2@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 00022 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00028 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00031 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00036 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0003a 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ 00041 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00045 33 c0 xor eax, eax ; 1756 : } 00047 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 0004c 48 83 c4 20 add rsp, 32 ; 00000020H 00050 41 5e pop r14 00052 5f pop rdi 00053 5e pop rsi 00054 c3 ret 0 $LN2@stbi__jpeg: ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 00055 83 b9 24 48 00 00 10 cmp DWORD PTR [rcx+18468], 16 0005c 7d 05 jge SHORT $LN3@stbi__jpeg 0005e e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN3@stbi__jpeg: ; 1736 : ; 1737 : if (j->succ_high == 0) { 00063 83 bb 3c 48 00 00 00 cmp DWORD PTR [rbx+18492], 0 0006a 48 89 6c 24 40 mov QWORD PTR [rsp+64], rbp 0006f 4c 89 7c 24 48 mov QWORD PTR [rsp+72], r15 00074 0f 85 98 02 00 00 jne $LN4@stbi__jpeg ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now 0007a 0f 57 c0 xorps xmm0, xmm0 0007d 0f 11 06 movups XMMWORD PTR [rsi], xmm0 00080 0f 11 46 10 movups XMMWORD PTR [rsi+16], xmm0 00084 0f 11 46 20 movups XMMWORD PTR [rsi+32], xmm0 00088 0f 11 46 30 movups XMMWORD PTR [rsi+48], xmm0 0008c 0f 11 46 40 movups XMMWORD PTR [rsi+64], xmm0 00090 0f 11 46 50 movups XMMWORD PTR [rsi+80], xmm0 00094 0f 11 46 60 movups XMMWORD PTR [rsi+96], xmm0 00098 0f 11 46 70 movups XMMWORD PTR [rsi+112], xmm0 ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 0009c 83 bb 24 48 00 00 10 cmp DWORD PTR [rbx+18468], 16 000a3 7d 08 jge SHORT $LN20@stbi__jpeg 000a5 48 8b cb mov rcx, rbx 000a8 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN20@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 000ad 44 8b 93 20 48 00 00 mov r10d, DWORD PTR [rbx+18464] ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { 000b4 4c 8d 3d 00 00 00 00 lea r15, OFFSET FLAT:__ImageBase 000bb 41 8b c2 mov eax, r10d 000be 48 c1 e8 17 shr rax, 23 000c2 0f b6 0c 38 movzx ecx, BYTE PTR [rax+rdi] 000c6 80 f9 ff cmp cl, 255 ; 000000ffH 000c9 73 21 jae SHORT $LN21@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 000cb 44 8b 8b 24 48 00 00 mov r9d, DWORD PTR [rbx+18468] 000d2 8b c1 mov eax, ecx 000d4 0f b6 8c 39 00 05 00 00 movzx ecx, BYTE PTR [rcx+rdi+1280] 000dc 41 3b c9 cmp ecx, r9d 000df 7f 44 jg SHORT $LN7@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 000e1 41 d3 e2 shl r10d, cl ; 1575 : j->code_bits -= s; 000e4 44 2b c9 sub r9d, ecx ; 1576 : return h->values[k]; 000e7 e9 9e 00 00 00 jmp $LN86@stbi__jpeg $LN21@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 000ec 41 8b ca mov ecx, r10d ; 1587 : if (temp < h->maxcode[k]) 000ef 48 8d 87 2c 06 00 00 lea rax, QWORD PTR [rdi+1580] 000f6 c1 e9 10 shr ecx, 16 000f9 41 b8 0a 00 00 00 mov r8d, 10 000ff 3b 08 cmp ecx, DWORD PTR [rax] 00101 72 0b jb SHORT $LN54@stbi__jpeg $LL19@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 00103 41 ff c0 inc r8d 00106 48 8d 40 04 lea rax, QWORD PTR [rax+4] ; 1587 : if (temp < h->maxcode[k]) 0010a 3b 08 cmp ecx, DWORD PTR [rax] 0010c 73 f5 jae SHORT $LL19@stbi__jpeg $LN54@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 0010e 44 8b 8b 24 48 00 00 mov r9d, DWORD PTR [rbx+18468] 00115 41 83 f8 11 cmp r8d, 17 00119 75 34 jne SHORT $LN24@stbi__jpeg ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; 0011b 41 8d 41 f0 lea eax, DWORD PTR [r9-16] 0011f 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax $LN7@stbi__jpeg: ; 431 : stbi__g_failure_reason = str; 00125 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0012b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00134 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00139 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0013d 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ 00144 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00148 33 c0 xor eax, eax 0014a e9 14 02 00 00 jmp $LN85@stbi__jpeg $LN24@stbi__jpeg: ; 1595 : if (k > j->code_bits) 0014f 45 3b c1 cmp r8d, r9d 00152 7f d1 jg SHORT $LN7@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 00154 49 63 c0 movsxd rax, r8d 00157 b9 20 00 00 00 mov ecx, 32 ; 00000020H 0015c 41 2b c8 sub ecx, r8d 0015f 45 8b da mov r11d, r10d 00162 41 d3 eb shr r11d, cl 00165 45 23 9c 87 00 00 00 00 and r11d, DWORD PTR stbi__bmask[r15+rax*4] 0016d 44 03 9c 87 4c 06 00 00 add r11d, DWORD PTR [rdi+rax*4+1612] ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 00175 41 81 fb ff 00 00 00 cmp r11d, 255 ; 000000ffH 0017c 77 a7 ja SHORT $LN7@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 0017e 45 2b c8 sub r9d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 00181 49 63 c3 movsxd rax, r11d 00184 41 8b c8 mov ecx, r8d 00187 41 d3 e2 shl r10d, cl $LN86@stbi__jpeg: ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 0018a 44 89 8b 24 48 00 00 mov DWORD PTR [rbx+18468], r9d 00191 44 89 93 20 48 00 00 mov DWORD PTR [rbx+18464], r10d 00198 0f b6 84 38 00 04 00 00 movzx eax, BYTE PTR [rax+rdi+1024] 001a0 0f b6 e8 movzx ebp, al 001a3 83 fd 0f cmp ebp, 15 001a6 0f 87 79 ff ff ff ja $LN7@stbi__jpeg ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; 001ac 33 ff xor edi, edi 001ae 84 c0 test al, al 001b0 74 66 je SHORT $LN12@stbi__jpeg ; 1619 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 001b2 44 3b cd cmp r9d, ebp 001b5 7d 08 jge SHORT $LN32@stbi__jpeg 001b7 48 8b cb mov rcx, rbx 001ba e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN32@stbi__jpeg: ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 001bf 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 001c6 44 3b d5 cmp r10d, ebp 001c9 7c 4d jl SHORT $LN12@stbi__jpeg ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) 001cb 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1623 : k = stbi_lrot(j->code_buffer, n); 001d2 8b cd mov ecx, ebp 001d4 45 8b c1 mov r8d, r9d ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; 001d7 44 2b d5 sub r10d, ebp 001da 41 d3 c0 rol r8d, cl 001dd 48 8d 0c ad 00 00 00 00 lea rcx, QWORD PTR [rbp*4] 001e5 42 8b 94 39 00 00 00 00 mov edx, DWORD PTR stbi__bmask[rcx+r15] 001ed 8b c2 mov eax, edx 001ef 41 c1 e9 1f shr r9d, 31 001f3 f7 d0 not eax ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); 001f5 41 ff c9 dec r9d 001f8 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 001ff 46 23 8c 39 00 00 00 00 and r9d, DWORD PTR stbi__jbias[rcx+r15] 00207 41 23 c0 and eax, r8d 0020a 41 23 d0 and edx, r8d 0020d 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax 00213 44 03 ca add r9d, edx ; 1628 : } 00216 eb 03 jmp SHORT $LN13@stbi__jpeg $LN12@stbi__jpeg: ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00218 44 8b cf mov r9d, edi $LN13@stbi__jpeg: 0021b 4f 8d 14 76 lea r10, QWORD PTR [r14+r14*2] ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 0021f 41 8b c9 mov ecx, r9d ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00222 49 c1 e2 05 shl r10, 5 ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 00226 f7 d1 not ecx ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00228 41 8b 94 1a b8 46 00 00 mov edx, DWORD PTR [r10+rbx+18104] ; 523 : if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow 00230 8b c2 mov eax, edx 00232 f7 d0 not eax 00234 33 c8 xor ecx, eax 00236 78 57 js SHORT $LN8@stbi__jpeg ; 524 : if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0. 00238 85 d2 test edx, edx 0023a 79 16 jns SHORT $LN37@stbi__jpeg 0023c 45 85 c9 test r9d, r9d 0023f 79 11 jns SHORT $LN37@stbi__jpeg 00241 b8 00 00 00 80 mov eax, -2147483648 ; ffffffff80000000H 00246 8b cf mov ecx, edi 00248 41 2b c1 sub eax, r9d 0024b 3b d0 cmp edx, eax 0024d 0f 9d c1 setge cl 00250 eb 0f jmp SHORT $LN35@stbi__jpeg $LN37@stbi__jpeg: ; 525 : return a <= INT_MAX - b; 00252 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00257 8b cf mov ecx, edi 00259 41 2b c1 sub eax, r9d 0025c 3b d0 cmp edx, eax 0025e 0f 9e c1 setle cl $LN35@stbi__jpeg: ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00261 85 c9 test ecx, ecx 00263 75 2a jne SHORT $LN8@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 00265 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0026b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00274 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00279 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0027d 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09IFDKCGFO@bad?5delta@ 00284 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); 00288 33 c0 xor eax, eax 0028a e9 d4 00 00 00 jmp $LN85@stbi__jpeg $LN8@stbi__jpeg: ; 1745 : dc = j->img_comp[b].dc_pred + diff; 0028f 46 8d 04 0a lea r8d, DWORD PTR [rdx+r9] ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00293 41 b9 01 00 00 00 mov r9d, 1 00299 45 89 84 1a b8 46 00 00 mov DWORD PTR [r10+rbx+18104], r8d 002a1 8b 8b 40 48 00 00 mov ecx, DWORD PTR [rbx+18496] 002a7 66 41 d3 e1 shl r9w, cl ; 531 : if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow 002ab 41 8d 41 01 lea eax, DWORD PTR [r9+1] 002af 66 83 f8 01 cmp ax, 1 002b3 76 4d jbe SHORT $LN43@stbi__jpeg ; 532 : if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX / b; // product is positive, so similar to mul2sizes_valid 002b5 41 0f b7 c1 movzx eax, r9w 002b9 45 0f bf d1 movsx r10d, r9w 002bd 66 41 33 c0 xor ax, r8w 002c1 41 0f bf c8 movsx ecx, r8w 002c5 66 0f ba e0 0f bt ax, 15 002ca 72 11 jb SHORT $LN44@stbi__jpeg 002cc b8 ff 7f 00 00 mov eax, 32767 ; 00007fffH 002d1 99 cdq 002d2 41 f7 fa idiv r10d 002d5 3b c8 cmp ecx, eax 002d7 40 0f 9e c7 setle dil 002db eb 1d jmp SHORT $LN41@stbi__jpeg $LN44@stbi__jpeg: ; 533 : if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN 002dd b8 00 80 ff ff mov eax, -32768 ; ffffffffffff8000H 002e2 99 cdq 002e3 41 f7 fa idiv r10d 002e6 66 45 85 c9 test r9w, r9w 002ea 79 08 jns SHORT $LN45@stbi__jpeg 002ec 3b c8 cmp ecx, eax 002ee 40 0f 9e c7 setle dil 002f2 eb 06 jmp SHORT $LN41@stbi__jpeg $LN45@stbi__jpeg: ; 534 : return a >= SHRT_MIN / b; 002f4 3b c8 cmp ecx, eax 002f6 40 0f 9d c7 setge dil $LN41@stbi__jpeg: ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 002fa 85 ff test edi, edi 002fc 0f 84 23 fe ff ff je $LN7@stbi__jpeg $LN43@stbi__jpeg: ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); 00302 41 0f bf c0 movsx eax, r8w 00306 41 0f bf c9 movsx ecx, r9w 0030a 0f af c8 imul ecx, eax 0030d 66 89 0e mov WORD PTR [rsi], cx ; 1749 : } 00310 eb 4c jmp SHORT $LN10@stbi__jpeg $LN4@stbi__jpeg: ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); 00312 83 bb 24 48 00 00 01 cmp DWORD PTR [rbx+18468], 1 00319 7d 08 jge SHORT $LN50@stbi__jpeg 0031b 48 8b cb mov rcx, rbx 0031e e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN50@stbi__jpeg: ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing 00323 44 8b 83 24 48 00 00 mov r8d, DWORD PTR [rbx+18468] 0032a 41 83 f8 01 cmp r8d, 1 0032e 7c 2e jl SHORT $LN10@stbi__jpeg ; 1648 : k = j->code_buffer; 00330 8b 93 20 48 00 00 mov edx, DWORD PTR [rbx+18464] ; 1649 : j->code_buffer <<= 1; 00336 8d 0c 12 lea ecx, DWORD PTR [rdx+rdx] 00339 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], ecx ; 1650 : --j->code_bits; 0033f 41 8d 48 ff lea ecx, DWORD PTR [r8-1] 00343 89 8b 24 48 00 00 mov DWORD PTR [rbx+18468], ecx ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) 00349 85 d2 test edx, edx 0034b 79 11 jns SHORT $LN10@stbi__jpeg ; 1753 : data[0] += (short)(1 << j->succ_low); 0034d 8b 8b 40 48 00 00 mov ecx, DWORD PTR [rbx+18496] 00353 ba 01 00 00 00 mov edx, 1 00358 66 d3 e2 shl dx, cl 0035b 66 01 16 add WORD PTR [rsi], dx $LN10@stbi__jpeg: ; 1754 : } ; 1755 : return 1; 0035e b8 01 00 00 00 mov eax, 1 $LN85@stbi__jpeg: 00363 48 8b 6c 24 40 mov rbp, QWORD PTR [rsp+64] 00368 4c 8b 7c 24 48 mov r15, QWORD PTR [rsp+72] ; 1756 : } 0036d 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 00372 48 83 c4 20 add rsp, 32 ; 00000020H 00376 41 5e pop r14 00378 5f pop rdi 00379 5e pop rsi 0037a c3 ret 0 stbi__jpeg_decode_block_prog_dc ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_decode_block_prog_ac _TEXT SEGMENT j$ = 96 data$ = 104 hac$ = 112 fac$ = 120 stbi__jpeg_decode_block_prog_ac PROC ; COMDAT ; 1761 : { 00000 4c 89 44 24 18 mov QWORD PTR [rsp+24], r8 00005 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx 0000a 53 push rbx 0000b 56 push rsi 0000c 57 push rdi 0000d 41 54 push r12 0000f 41 57 push r15 00011 48 83 ec 30 sub rsp, 48 ; 00000030H ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 00015 48 63 b9 34 48 00 00 movsxd rdi, DWORD PTR [rcx+18484] 0001c 4d 8b f9 mov r15, r9 0001f 49 8b f0 mov rsi, r8 00022 4c 8b e2 mov r12, rdx 00025 48 8b d9 mov rbx, rcx 00028 85 ff test edi, edi 0002a 75 31 jne SHORT $LN13@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 0002c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00032 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0003b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00040 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00044 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BG@PJBJDAGM@can?8t?5merge?5dc?5and?5ac@ 0004b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); 0004f 33 c0 xor eax, eax ; 1885 : } 00051 48 83 c4 30 add rsp, 48 ; 00000030H 00055 41 5f pop r15 00057 41 5c pop r12 00059 5f pop rdi 0005a 5e pop rsi 0005b 5b pop rbx 0005c c3 ret 0 $LN13@stbi__jpeg: ; 1764 : ; 1765 : if (j->succ_high == 0) { 0005d 83 b9 3c 48 00 00 00 cmp DWORD PTR [rcx+18492], 0 00064 8b 81 44 48 00 00 mov eax, DWORD PTR [rcx+18500] 0006a 48 89 6c 24 60 mov QWORD PTR [rsp+96], rbp 0006f 4c 89 6c 24 28 mov QWORD PTR [rsp+40], r13 00074 4c 89 74 24 20 mov QWORD PTR [rsp+32], r14 00079 44 8b b1 40 48 00 00 mov r14d, DWORD PTR [rcx+18496] 00080 0f 85 e1 02 00 00 jne $LN14@stbi__jpeg ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { 00086 85 c0 test eax, eax 00088 74 12 je SHORT $LN16@stbi__jpeg ; 1769 : --j->eob_run; 0008a ff c8 dec eax 0008c 89 81 44 48 00 00 mov DWORD PTR [rcx+18500], eax ; 1770 : return 1; 00092 b8 01 00 00 00 mov eax, 1 00097 e9 4c 06 00 00 jmp $LN209@stbi__jpeg $LN16@stbi__jpeg: ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; 0009c 4c 8d 2d 00 00 00 00 lea r13, OFFSET FLAT:__ImageBase $LL4@stbi__jpeg: ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 000a3 83 bb 24 48 00 00 10 cmp DWORD PTR [rbx+18468], 16 000aa 7d 08 jge SHORT $LN17@stbi__jpeg 000ac 48 8b cb mov rcx, rbx 000af e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN17@stbi__jpeg: ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 000b4 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1779 : r = fac[c]; 000bb 44 8b 83 24 48 00 00 mov r8d, DWORD PTR [rbx+18468] 000c2 41 8b c1 mov eax, r9d 000c5 48 c1 e8 17 shr rax, 23 000c9 41 0f bf 14 47 movsx edx, WORD PTR [r15+rax*2] ; 1780 : if (r) { // fast-AC path 000ce 85 d2 test edx, edx 000d0 74 5b je SHORT $LN18@stbi__jpeg ; 1781 : k += (r >> 4) & 15; // run 000d2 8b c2 mov eax, edx ; 1782 : s = r & 15; // combined length 000d4 8b ca mov ecx, edx 000d6 c1 f8 04 sar eax, 4 000d9 83 e1 0f and ecx, 15 000dc 83 e0 0f and eax, 15 000df 03 f8 add edi, eax ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); 000e1 41 3b c8 cmp ecx, r8d 000e4 0f 8f d9 05 00 00 jg $LN149@stbi__jpeg ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; 000ea 44 2b c1 sub r8d, ecx 000ed 41 d3 e1 shl r9d, cl ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); 000f0 41 8b ce mov ecx, r14d 000f3 44 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], r8d 000fa b8 01 00 00 00 mov eax, 1 000ff 4c 63 c7 movsxd r8, edi 00102 66 d3 e0 shl ax, cl 00105 ff c7 inc edi 00107 c1 fa 08 sar edx, 8 0010a 0f bf c8 movsx ecx, ax 0010d 43 0f b6 84 28 00 00 00 00 movzx eax, BYTE PTR stbi__jpeg_dezigzag[r8+r13] 00116 0f bf d2 movsx edx, dx 00119 0f af d1 imul edx, ecx 0011c 44 89 8b 20 48 00 00 mov DWORD PTR [rbx+18464], r9d 00123 66 41 89 14 44 mov WORD PTR [r12+rax*2], dx ; 1788 : } 00128 e9 8d 01 00 00 jmp $LN2@stbi__jpeg $LN18@stbi__jpeg: ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 0012d 41 83 f8 10 cmp r8d, 16 00131 7d 08 jge SHORT $LN58@stbi__jpeg 00133 48 8b cb mov rcx, rbx 00136 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN58@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 0013b 44 8b 9b 20 48 00 00 mov r11d, DWORD PTR [rbx+18464] 00142 41 8b c3 mov eax, r11d 00145 48 c1 e8 17 shr rax, 23 ; 1569 : k = h->fast[c]; 00149 0f b6 0c 30 movzx ecx, BYTE PTR [rax+rsi] ; 1570 : if (k < 255) { 0014d 80 f9 ff cmp cl, 255 ; 000000ffH 00150 73 22 jae SHORT $LN59@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 00152 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00159 8b c1 mov eax, ecx 0015b 0f b6 8c 31 00 05 00 00 movzx ecx, BYTE PTR [rcx+rsi+1280] 00163 41 3b ca cmp ecx, r10d 00166 0f 8f 57 05 00 00 jg $LN149@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 0016c 41 d3 e3 shl r11d, cl ; 1575 : j->code_bits -= s; 0016f 44 2b d1 sub r10d, ecx ; 1576 : return h->values[k]; 00172 eb 7d jmp SHORT $LN210@stbi__jpeg $LN59@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 00174 41 8b cb mov ecx, r11d ; 1587 : if (temp < h->maxcode[k]) 00177 48 8d 86 2c 06 00 00 lea rax, QWORD PTR [rsi+1580] 0017e c1 e9 10 shr ecx, 16 00181 41 b8 0a 00 00 00 mov r8d, 10 00187 45 8b c8 mov r9d, r8d 0018a 3b 08 cmp ecx, DWORD PTR [rax] 0018c 72 10 jb SHORT $LN119@stbi__jpeg 0018e 66 90 npad 2 $LL57@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 00190 41 ff c0 inc r8d 00193 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00197 49 ff c1 inc r9 ; 1587 : if (temp < h->maxcode[k]) 0019a 3b 08 cmp ecx, DWORD PTR [rax] 0019c 73 f2 jae SHORT $LL57@stbi__jpeg $LN119@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 0019e 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 001a5 41 83 f8 11 cmp r8d, 17 001a9 0f 84 af 01 00 00 je $LN145@stbi__jpeg ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) 001af 45 3b c2 cmp r8d, r10d 001b2 0f 8f 0b 05 00 00 jg $LN149@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 001b8 b9 20 00 00 00 mov ecx, 32 ; 00000020H 001bd 41 8b d3 mov edx, r11d 001c0 41 2b c8 sub ecx, r8d 001c3 d3 ea shr edx, cl 001c5 43 23 94 8d 00 00 00 00 and edx, DWORD PTR stbi__bmask[r13+r9*4] 001cd 46 8b 8c 8e 4c 06 00 00 mov r9d, DWORD PTR [rsi+r9*4+1612] 001d5 44 03 ca add r9d, edx ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 001d8 41 81 f9 ff 00 00 00 cmp r9d, 255 ; 000000ffH 001df 0f 87 de 04 00 00 ja $LN149@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 001e5 45 2b d0 sub r10d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 001e8 49 63 c1 movsxd rax, r9d 001eb 41 8b c8 mov ecx, r8d 001ee 41 d3 e3 shl r11d, cl $LN210@stbi__jpeg: ; 1792 : s = rs & 15; 001f1 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 001f8 44 89 9b 20 48 00 00 mov DWORD PTR [rbx+18464], r11d 001ff 0f b6 b4 30 00 04 00 00 movzx esi, BYTE PTR [rax+rsi+1024] 00207 8b ee mov ebp, esi ; 1793 : r = rs >> 4; 00209 c1 ee 04 shr esi, 4 0020c 83 e5 0f and ebp, 15 ; 1794 : if (s == 0) { 0020f 75 11 jne SHORT $LN22@stbi__jpeg ; 1795 : if (r < 15) { 00211 83 fe 0f cmp esi, 15 00214 0f 82 b6 00 00 00 jb $LN122@stbi__jpeg ; 1800 : break; ; 1801 : } ; 1802 : k += 16; 0021a 83 c7 10 add edi, 16 ; 1803 : } 0021d e9 93 00 00 00 jmp $LN211@stbi__jpeg $LN22@stbi__jpeg: ; 1804 : else { ; 1805 : k += r; 00222 03 fe add edi, esi ; 1806 : zig = stbi__jpeg_dezigzag[k++]; 00224 48 63 c7 movsxd rax, edi 00227 ff c7 inc edi 00229 42 0f b6 b4 28 00 00 00 00 movzx esi, BYTE PTR stbi__jpeg_dezigzag[rax+r13] ; 1619 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 00232 44 3b d5 cmp r10d, ebp 00235 7d 08 jge SHORT $LN74@stbi__jpeg 00237 48 8b cb mov rcx, rbx 0023a e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN74@stbi__jpeg: ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 0023f 44 8b 93 24 48 00 00 mov r10d, DWORD PTR [rbx+18468] 00246 44 3b d5 cmp r10d, ebp 00249 7d 05 jge SHORT $LN75@stbi__jpeg 0024b 45 33 c9 xor r9d, r9d 0024e eb 4b jmp SHORT $LN73@stbi__jpeg $LN75@stbi__jpeg: ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) 00250 44 8b 8b 20 48 00 00 mov r9d, DWORD PTR [rbx+18464] ; 1623 : k = stbi_lrot(j->code_buffer, n); 00257 8b cd mov ecx, ebp 00259 45 8b c1 mov r8d, r9d ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; 0025c 44 2b d5 sub r10d, ebp 0025f 41 d3 c0 rol r8d, cl 00262 48 8d 0c ad 00 00 00 00 lea rcx, QWORD PTR [rbp*4] 0026a 42 8b 94 29 00 00 00 00 mov edx, DWORD PTR stbi__bmask[rcx+r13] 00272 8b c2 mov eax, edx 00274 41 c1 e9 1f shr r9d, 31 00278 f7 d0 not eax ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); 0027a 41 ff c9 dec r9d 0027d 44 89 93 24 48 00 00 mov DWORD PTR [rbx+18468], r10d 00284 46 23 8c 29 00 00 00 00 and r9d, DWORD PTR stbi__jbias[rcx+r13] 0028c 41 23 c0 and eax, r8d 0028f 41 23 d0 and edx, r8d 00292 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax 00298 44 03 ca add r9d, edx $LN73@stbi__jpeg: ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); 0029b 41 8b ce mov ecx, r14d 0029e 41 0f bf c1 movsx eax, r9w 002a2 ba 01 00 00 00 mov edx, 1 002a7 66 d3 e2 shl dx, cl 002aa 0f bf ca movsx ecx, dx 002ad 0f af c8 imul ecx, eax 002b0 66 41 89 0c 74 mov WORD PTR [r12+rsi*2], cx $LN211@stbi__jpeg: ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); 002b5 48 8b 74 24 70 mov rsi, QWORD PTR hac$[rsp] $LN2@stbi__jpeg: 002ba 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] 002c0 0f 8e dd fd ff ff jle $LL4@stbi__jpeg ; 1882 : } ; 1883 : } ; 1884 : return 1; 002c6 b8 01 00 00 00 mov eax, 1 002cb e9 18 04 00 00 jmp $LN209@stbi__jpeg $LN122@stbi__jpeg: ; 1796 : j->eob_run = (1 << r); 002d0 8b ce mov ecx, esi 002d2 41 b8 01 00 00 00 mov r8d, 1 002d8 41 d3 e0 shl r8d, cl 002db 44 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], r8d ; 1797 : if (r) 002e2 85 f6 test esi, esi 002e4 74 64 je SHORT $LN25@stbi__jpeg ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 002e6 44 3b d6 cmp r10d, esi 002e9 7d 0f jge SHORT $LN70@stbi__jpeg 002eb 48 8b cb mov rcx, rbx 002ee e8 00 00 00 00 call stbi__grow_buffer_unsafe 002f3 44 8b 83 44 48 00 00 mov r8d, DWORD PTR [rbx+18500] $LN70@stbi__jpeg: ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 002fa 44 8b 8b 24 48 00 00 mov r9d, DWORD PTR [rbx+18468] 00301 44 3b ce cmp r9d, esi 00304 7d 17 jge SHORT $LN71@stbi__jpeg 00306 33 c9 xor ecx, ecx ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); 00308 44 03 c1 add r8d, ecx ; 1799 : --j->eob_run; 0030b 41 8d 40 ff lea eax, DWORD PTR [r8-1] 0030f 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], eax ; 1882 : } ; 1883 : } ; 1884 : return 1; 00315 8d 41 01 lea eax, QWORD PTR [rcx+1] 00318 e9 cb 03 00 00 jmp $LN209@stbi__jpeg $LN71@stbi__jpeg: ; 1636 : k = stbi_lrot(j->code_buffer, n); 0031d 8b 93 20 48 00 00 mov edx, DWORD PTR [rbx+18464] 00323 8b ce mov ecx, esi 00325 d3 c2 rol edx, cl ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; 00327 44 2b ce sub r9d, esi 0032a 41 8b 8c b5 00 00 00 00 mov ecx, DWORD PTR stbi__bmask[r13+rsi*4] 00332 8b c1 mov eax, ecx 00334 f7 d0 not eax 00336 44 89 8b 24 48 00 00 mov DWORD PTR [rbx+18468], r9d 0033d 23 c2 and eax, edx 0033f 23 ca and ecx, edx 00341 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); 00347 44 03 c1 add r8d, ecx $LN25@stbi__jpeg: ; 1799 : --j->eob_run; 0034a 41 8d 40 ff lea eax, DWORD PTR [r8-1] 0034e 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], eax ; 1882 : } ; 1883 : } ; 1884 : return 1; 00354 b8 01 00 00 00 mov eax, 1 00359 e9 8a 03 00 00 jmp $LN209@stbi__jpeg $LN145@stbi__jpeg: ; 1591 : j->code_bits -= 16; 0035e 41 8d 42 f0 lea eax, DWORD PTR [r10-16] ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); 00362 e9 56 03 00 00 jmp $LN212@stbi__jpeg $LN14@stbi__jpeg: ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); 00367 bd 01 00 00 00 mov ebp, 1 0036c 41 8b ce mov ecx, r14d 0036f 66 d3 e5 shl bp, cl ; 1816 : ; 1817 : if (j->eob_run) { 00372 85 c0 test eax, eax 00374 0f 84 9d 00 00 00 je $LN26@stbi__jpeg ; 1818 : --j->eob_run; 0037a ff c8 dec eax 0037c 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], eax ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { 00382 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] 00388 0f 8f 24 03 00 00 jg $LN9@stbi__jpeg 0038e 4c 8d 2d 00 00 00 00 lea r13, OFFSET FLAT:__ImageBase 00395 4d 8d b5 00 00 00 00 lea r14, QWORD PTR stbi__jpeg_dezigzag[r13] 0039c 4c 03 f7 add r14, rdi 0039f 90 npad 1 $LL7@stbi__jpeg: ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; 003a0 41 0f b6 06 movzx eax, BYTE PTR [r14] ; 1821 : if (*p != 0) 003a4 66 41 83 3c 44 00 cmp WORD PTR [r12+rax*2], 0 003aa 49 8d 34 44 lea rsi, QWORD PTR [r12+rax*2] 003ae 74 50 je SHORT $LN5@stbi__jpeg ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); 003b0 83 bb 24 48 00 00 01 cmp DWORD PTR [rbx+18468], 1 003b7 7d 08 jge SHORT $LN78@stbi__jpeg 003b9 48 8b cb mov rcx, rbx 003bc e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN78@stbi__jpeg: ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing 003c1 8b 93 24 48 00 00 mov edx, DWORD PTR [rbx+18468] 003c7 83 fa 01 cmp edx, 1 003ca 7c 34 jl SHORT $LN5@stbi__jpeg ; 1648 : k = j->code_buffer; 003cc 8b 8b 20 48 00 00 mov ecx, DWORD PTR [rbx+18464] ; 1649 : j->code_buffer <<= 1; 003d2 8d 04 09 lea eax, DWORD PTR [rcx+rcx] 003d5 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax ; 1650 : --j->code_bits; 003db 8d 42 ff lea eax, DWORD PTR [rdx-1] 003de 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax ; 1822 : if (stbi__jpeg_get_bit(j)) 003e4 85 c9 test ecx, ecx 003e6 79 18 jns SHORT $LN5@stbi__jpeg ; 1823 : if ((*p & bit) == 0) { 003e8 0f b7 06 movzx eax, WORD PTR [rsi] 003eb 66 85 c5 test ax, bp 003ee 75 10 jne SHORT $LN5@stbi__jpeg ; 1824 : if (*p > 0) 003f0 66 85 c0 test ax, ax 003f3 7e 05 jle SHORT $LN31@stbi__jpeg ; 1825 : *p += bit; 003f5 66 03 c5 add ax, bp 003f8 eb 03 jmp SHORT $LN213@stbi__jpeg $LN31@stbi__jpeg: ; 1826 : else ; 1827 : *p -= bit; 003fa 66 2b c5 sub ax, bp $LN213@stbi__jpeg: ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { 003fd 66 89 06 mov WORD PTR [rsi], ax $LN5@stbi__jpeg: 00400 ff c7 inc edi 00402 49 ff c6 inc r14 00405 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] 0040b 7e 93 jle SHORT $LL7@stbi__jpeg ; 1882 : } ; 1883 : } ; 1884 : return 1; 0040d b8 01 00 00 00 mov eax, 1 00412 e9 d1 02 00 00 jmp $LN209@stbi__jpeg $LN26@stbi__jpeg: ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; 00417 4c 8b e7 mov r12, rdi 0041a 4c 8d 2d 00 00 00 00 lea r13, OFFSET FLAT:__ImageBase 00421 45 33 f6 xor r14d, r14d $LL10@stbi__jpeg: ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); 00424 83 bb 24 48 00 00 10 cmp DWORD PTR [rbx+18468], 16 0042b 7d 08 jge SHORT $LN85@stbi__jpeg 0042d 48 8b cb mov rcx, rbx 00430 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN85@stbi__jpeg: ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); 00435 8b 93 20 48 00 00 mov edx, DWORD PTR [rbx+18464] 0043b 8b c2 mov eax, edx 0043d 48 c1 e8 17 shr rax, 23 ; 1569 : k = h->fast[c]; 00441 0f b6 0c 30 movzx ecx, BYTE PTR [rax+rsi] ; 1570 : if (k < 255) { 00445 80 f9 ff cmp cl, 255 ; 000000ffH 00448 73 2a jae SHORT $LN86@stbi__jpeg ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) 0044a 44 8b 8b 24 48 00 00 mov r9d, DWORD PTR [rbx+18468] 00451 8b c1 mov eax, ecx 00453 0f b6 8c 31 00 05 00 00 movzx ecx, BYTE PTR [rcx+rsi+1280] 0045b 41 3b c9 cmp ecx, r9d 0045e 0f 8f 5f 02 00 00 jg $LN149@stbi__jpeg ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; 00464 d3 e2 shl edx, cl 00466 89 93 20 48 00 00 mov DWORD PTR [rbx+18464], edx ; 1575 : j->code_bits -= s; 0046c 44 2b c9 sub r9d, ecx ; 1576 : return h->values[k]; 0046f e9 8b 00 00 00 jmp $LN214@stbi__jpeg $LN86@stbi__jpeg: ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; 00474 c1 ea 10 shr edx, 16 ; 1587 : if (temp < h->maxcode[k]) 00477 48 8d 86 2c 06 00 00 lea rax, QWORD PTR [rsi+1580] 0047e 41 b8 0a 00 00 00 mov r8d, 10 00484 45 8b d0 mov r10d, r8d 00487 3b 10 cmp edx, DWORD PTR [rax] 00489 72 13 jb SHORT $LN123@stbi__jpeg 0048b 0f 1f 44 00 00 npad 5 $LL84@stbi__jpeg: ; 1586 : for (k = FAST_BITS + 1; ; ++k) 00490 41 ff c0 inc r8d 00493 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00497 49 ff c2 inc r10 ; 1587 : if (temp < h->maxcode[k]) 0049a 3b 10 cmp edx, DWORD PTR [rax] 0049c 73 f2 jae SHORT $LL84@stbi__jpeg $LN123@stbi__jpeg: ; 1588 : break; ; 1589 : if (k == 17) { 0049e 44 8b 8b 24 48 00 00 mov r9d, DWORD PTR [rbx+18468] 004a5 41 83 f8 11 cmp r8d, 17 004a9 0f 84 0a 02 00 00 je $LN148@stbi__jpeg ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) 004af 45 3b c1 cmp r8d, r9d 004b2 0f 8f 0b 02 00 00 jg $LN149@stbi__jpeg ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; 004b8 44 8b 9b 20 48 00 00 mov r11d, DWORD PTR [rbx+18464] 004bf b9 20 00 00 00 mov ecx, 32 ; 00000020H 004c4 41 2b c8 sub ecx, r8d 004c7 41 8b d3 mov edx, r11d 004ca d3 ea shr edx, cl 004cc 43 23 94 95 00 00 00 00 and edx, DWORD PTR stbi__bmask[r13+r10*4] 004d4 46 8b 94 96 4c 06 00 00 mov r10d, DWORD PTR [rsi+r10*4+1612] 004dc 44 03 d2 add r10d, edx ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! 004df 41 81 fa ff 00 00 00 cmp r10d, 255 ; 000000ffH 004e6 0f 87 d7 01 00 00 ja $LN149@stbi__jpeg ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; 004ec 45 2b c8 sub r9d, r8d ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; 004ef 49 63 c2 movsxd rax, r10d 004f2 41 8b c8 mov ecx, r8d 004f5 41 d3 e3 shl r11d, cl 004f8 44 89 9b 20 48 00 00 mov DWORD PTR [rbx+18464], r11d $LN214@stbi__jpeg: ; 1837 : s = rs & 15; 004ff 44 89 8b 24 48 00 00 mov DWORD PTR [rbx+18468], r9d 00506 0f b6 b4 30 00 04 00 00 movzx esi, BYTE PTR [rax+rsi+1024] 0050e 44 8b fe mov r15d, esi ; 1838 : r = rs >> 4; 00511 c1 ee 04 shr esi, 4 00514 41 83 e7 0f and r15d, 15 ; 1839 : if (s == 0) { 00518 0f 85 94 00 00 00 jne $LN34@stbi__jpeg ; 1840 : if (r < 15) { 0051e 83 fe 0f cmp esi, 15 00521 0f 83 d0 00 00 00 jae $LN116@stbi__jpeg ; 1841 : j->eob_run = (1 << r) - 1; 00527 8b ce mov ecx, esi 00529 41 ba 01 00 00 00 mov r10d, 1 0052f 41 d3 e2 shl r10d, cl 00532 41 ff ca dec r10d 00535 44 89 93 44 48 00 00 mov DWORD PTR [rbx+18500], r10d ; 1842 : if (r) 0053c 85 f6 test esi, esi 0053e 74 6b je SHORT $LN150@stbi__jpeg ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); 00540 44 3b ce cmp r9d, esi 00543 7d 0f jge SHORT $LN97@stbi__jpeg 00545 48 8b cb mov rcx, rbx 00548 e8 00 00 00 00 call stbi__grow_buffer_unsafe 0054d 44 8b 93 44 48 00 00 mov r10d, DWORD PTR [rbx+18500] $LN97@stbi__jpeg: ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing 00554 44 8b 83 24 48 00 00 mov r8d, DWORD PTR [rbx+18468] 0055b 44 3b c6 cmp r8d, esi 0055e 7d 17 jge SHORT $LN98@stbi__jpeg 00560 41 8b ce mov ecx, r14d ; 1844 : r = 64; // force end of block 00563 be 40 00 00 00 mov esi, 64 ; 00000040H 00568 41 8d 04 0a lea eax, DWORD PTR [r10+rcx] 0056c 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], eax ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } 00572 e9 80 00 00 00 jmp $LN116@stbi__jpeg $LN98@stbi__jpeg: ; 1636 : k = stbi_lrot(j->code_buffer, n); 00577 8b 93 20 48 00 00 mov edx, DWORD PTR [rbx+18464] 0057d 8b ce mov ecx, esi 0057f d3 c2 rol edx, cl ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; 00581 44 2b c6 sub r8d, esi 00584 41 8b 8c b5 00 00 00 00 mov ecx, DWORD PTR stbi__bmask[r13+rsi*4] 0058c 8b c1 mov eax, ecx 0058e f7 d0 not eax 00590 44 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], r8d 00597 23 c2 and eax, edx 00599 23 ca and ecx, edx 0059b 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); 005a1 41 8d 04 0a lea eax, DWORD PTR [r10+rcx] 005a5 89 83 44 48 00 00 mov DWORD PTR [rbx+18500], eax $LN150@stbi__jpeg: ; 1844 : r = 64; // force end of block 005ab be 40 00 00 00 mov esi, 64 ; 00000040H ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } 005b0 eb 45 jmp SHORT $LN116@stbi__jpeg $LN34@stbi__jpeg: ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); 005b2 41 83 ff 01 cmp r15d, 1 005b6 0f 85 07 01 00 00 jne $LN149@stbi__jpeg ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); 005bc 45 3b cf cmp r9d, r15d 005bf 7d 08 jge SHORT $LN103@stbi__jpeg 005c1 48 8b cb mov rcx, rbx 005c4 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN103@stbi__jpeg: ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing 005c9 8b 93 24 48 00 00 mov edx, DWORD PTR [rbx+18468] 005cf 44 0f bf fd movsx r15d, bp 005d3 83 fa 01 cmp edx, 1 005d6 7c 1c jl SHORT $LN40@stbi__jpeg ; 1648 : k = j->code_buffer; 005d8 8b 8b 20 48 00 00 mov ecx, DWORD PTR [rbx+18464] ; 1649 : j->code_buffer <<= 1; 005de 8d 04 09 lea eax, DWORD PTR [rcx+rcx] 005e1 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax ; 1650 : --j->code_bits; 005e7 8d 42 ff lea eax, DWORD PTR [rdx-1] 005ea 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) 005f0 85 c9 test ecx, ecx 005f2 78 03 js SHORT $LN116@stbi__jpeg $LN40@stbi__jpeg: ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; 005f4 41 f7 df neg r15d $LN116@stbi__jpeg: ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { 005f7 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] 005fd 0f 8f a4 00 00 00 jg $LN215@stbi__jpeg 00603 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL11@stbi__jpeg: ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; 00610 43 0f b6 84 2c 00 00 00 00 movzx eax, BYTE PTR stbi__jpeg_dezigzag[r12+r13] 00619 ff c7 inc edi 0061b 48 8b 4c 24 68 mov rcx, QWORD PTR data$[rsp] 00620 49 ff c4 inc r12 ; 1864 : if (*p != 0) { 00623 66 83 3c 41 00 cmp WORD PTR [rcx+rax*2], 0 00628 4c 8d 34 41 lea r14, QWORD PTR [rcx+rax*2] 0062c 74 58 je SHORT $LN42@stbi__jpeg ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); 0062e 83 bb 24 48 00 00 01 cmp DWORD PTR [rbx+18468], 1 00635 7d 08 jge SHORT $LN107@stbi__jpeg 00637 48 8b cb mov rcx, rbx 0063a e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN107@stbi__jpeg: ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing 0063f 8b 93 24 48 00 00 mov edx, DWORD PTR [rbx+18468] 00645 83 fa 01 cmp edx, 1 00648 7c 42 jl SHORT $LN43@stbi__jpeg ; 1648 : k = j->code_buffer; 0064a 8b 8b 20 48 00 00 mov ecx, DWORD PTR [rbx+18464] ; 1649 : j->code_buffer <<= 1; 00650 8d 04 09 lea eax, DWORD PTR [rcx+rcx] 00653 89 83 20 48 00 00 mov DWORD PTR [rbx+18464], eax ; 1650 : --j->code_bits; 00659 8d 42 ff lea eax, DWORD PTR [rdx-1] 0065c 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax ; 1865 : if (stbi__jpeg_get_bit(j)) 00662 85 c9 test ecx, ecx 00664 79 26 jns SHORT $LN43@stbi__jpeg ; 1866 : if ((*p & bit) == 0) { 00666 41 0f b7 06 movzx eax, WORD PTR [r14] 0066a 66 85 c5 test ax, bp 0066d 75 1d jne SHORT $LN43@stbi__jpeg ; 1867 : if (*p > 0) 0066f 66 85 c0 test ax, ax 00672 7e 09 jle SHORT $LN46@stbi__jpeg ; 1868 : *p += bit; 00674 66 03 c5 add ax, bp 00677 66 41 89 06 mov WORD PTR [r14], ax 0067b eb 0f jmp SHORT $LN43@stbi__jpeg $LN46@stbi__jpeg: ; 1869 : else ; 1870 : *p -= bit; 0067d 66 2b c5 sub ax, bp 00680 66 41 89 06 mov WORD PTR [r14], ax ; 1871 : } ; 1872 : } 00684 eb 06 jmp SHORT $LN43@stbi__jpeg $LN42@stbi__jpeg: ; 1873 : else { ; 1874 : if (r == 0) { 00686 85 f6 test esi, esi 00688 74 10 je SHORT $LN124@stbi__jpeg ; 1876 : break; ; 1877 : } ; 1878 : --r; 0068a ff ce dec esi $LN43@stbi__jpeg: ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { 0068c 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] 00692 0f 8e 78 ff ff ff jle $LL11@stbi__jpeg ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); 00698 eb 04 jmp SHORT $LN216@stbi__jpeg $LN124@stbi__jpeg: ; 1875 : *p = (short)s; 0069a 66 45 89 3e mov WORD PTR [r14], r15w $LN216@stbi__jpeg: ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); 0069e 45 33 f6 xor r14d, r14d 006a1 3b bb 38 48 00 00 cmp edi, DWORD PTR [rbx+18488] $LN215@stbi__jpeg: 006a7 48 8b 74 24 70 mov rsi, QWORD PTR hac$[rsp] 006ac 0f 8e 72 fd ff ff jle $LL10@stbi__jpeg $LN9@stbi__jpeg: ; 1882 : } ; 1883 : } ; 1884 : return 1; 006b2 b8 01 00 00 00 mov eax, 1 006b7 eb 2f jmp SHORT $LN209@stbi__jpeg $LN148@stbi__jpeg: ; 1591 : j->code_bits -= 16; 006b9 41 8d 41 f0 lea eax, DWORD PTR [r9-16] $LN212@stbi__jpeg: 006bd 89 83 24 48 00 00 mov DWORD PTR [rbx+18468], eax $LN149@stbi__jpeg: ; 431 : stbi__g_failure_reason = str; 006c3 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 006c9 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006d2 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 006d7 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006db 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@IIMLINA@bad?5huffman?5code@ 006e2 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); 006e6 33 c0 xor eax, eax $LN209@stbi__jpeg: 006e8 4c 8b 6c 24 28 mov r13, QWORD PTR [rsp+40] 006ed 48 8b 6c 24 60 mov rbp, QWORD PTR [rsp+96] 006f2 4c 8b 74 24 20 mov r14, QWORD PTR [rsp+32] ; 1885 : } 006f7 48 83 c4 30 add rsp, 48 ; 00000030H 006fb 41 5f pop r15 006fd 41 5c pop r12 006ff 5f pop rdi 00700 5e pop rsi 00701 5b pop rbx 00702 c3 ret 0 stbi__jpeg_decode_block_prog_ac ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__clamp _TEXT SEGMENT x$ = 8 stbi__clamp PROC ; COMDAT ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { 00000 ba ff 00 00 00 mov edx, 255 ; 000000ffH 00005 3b ca cmp ecx, edx 00007 76 10 jbe SHORT $LN4@stbi__clam ; 1892 : if (x < 0) return 0; 00009 85 c9 test ecx, ecx 0000b 79 03 jns SHORT $LN3@stbi__clam 0000d 32 c0 xor al, al ; 1896 : } 0000f c3 ret 0 $LN3@stbi__clam: ; 1893 : if (x > 255) return 255; 00010 3b ca cmp ecx, edx 00012 0f b6 c1 movzx eax, cl 00015 0f 4f c2 cmovg eax, edx ; 1896 : } 00018 c3 ret 0 $LN4@stbi__clam: ; 1894 : } ; 1895 : return (stbi_uc)x; 00019 0f b6 c1 movzx eax, cl ; 1896 : } 0001c c3 ret 0 stbi__clamp ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__idct_block _TEXT SEGMENT $T9 = 0 $T10 = 0 t3$3$ = 0 tv2514 = 8 tv2499 = 8 out$GSCopy$1$ = 16 tv2511 = 16 out_stride$GSCopy$1$ = 24 val$ = 32 __$ArrayPad$ = 288 out$ = 368 out_stride$ = 376 data$ = 384 stbi__idct_block PROC ; COMDAT ; 1940 : { 00000 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx 00005 55 push rbp 00006 56 push rsi 00007 57 push rdi 00008 41 54 push r12 0000a 41 55 push r13 0000c 41 56 push r14 0000e 41 57 push r15 00010 48 81 ec 30 01 00 00 sub rsp, 304 ; 00000130H 00017 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0001e 48 33 c4 xor rax, rsp 00021 48 89 84 24 20 01 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00029 89 54 24 18 mov DWORD PTR out_stride$GSCopy$1$[rsp], edx 0002d 48 8d 6c 24 40 lea rbp, QWORD PTR val$[rsp+32] 00032 48 89 4c 24 10 mov QWORD PTR out$GSCopy$1$[rsp], rcx 00037 49 8d 40 20 lea rax, QWORD PTR [r8+32] 0003b 48 c7 44 24 08 04 00 00 00 mov QWORD PTR tv2514[rsp], 4 $LL4@stbi__idct: ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { 00044 0f bf 58 f0 movsx ebx, WORD PTR [rax-16] 00048 66 85 db test bx, bx 0004b 75 49 jne SHORT $LN8@stbi__idct 0004d 66 39 18 cmp WORD PTR [rax], bx 00050 75 44 jne SHORT $LN8@stbi__idct 00052 66 39 58 10 cmp WORD PTR [rax+16], bx 00056 75 3e jne SHORT $LN8@stbi__idct 00058 66 39 58 20 cmp WORD PTR [rax+32], bx 0005c 75 38 jne SHORT $LN8@stbi__idct 0005e 66 39 58 30 cmp WORD PTR [rax+48], bx 00062 75 32 jne SHORT $LN8@stbi__idct 00064 66 39 58 40 cmp WORD PTR [rax+64], bx 00068 75 2c jne SHORT $LN8@stbi__idct 0006a 66 39 58 50 cmp WORD PTR [rax+80], bx 0006e 75 26 jne SHORT $LN8@stbi__idct ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; 00070 0f bf 48 e0 movsx ecx, WORD PTR [rax-32] 00074 c1 e1 02 shl ecx, 2 ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; 00077 89 8d c0 00 00 00 mov DWORD PTR [rbp+192], ecx 0007d 44 8b e9 mov r13d, ecx 00080 89 8d a0 00 00 00 mov DWORD PTR [rbp+160], ecx 00086 8b d1 mov edx, ecx 00088 89 4d 20 mov DWORD PTR [rbp+32], ecx 0008b 89 4d 00 mov DWORD PTR [rbp], ecx 0008e 89 4d e0 mov DWORD PTR [rbp-32], ecx ; 1956 : } 00091 e9 3e 01 00 00 jmp $LN2@stbi__idct $LN8@stbi__idct: ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) 00096 44 0f bf 58 10 movsx r11d, WORD PTR [rax+16] 0009b 44 0f bf 08 movsx r9d, WORD PTR [rax] 0009f 0f bf 50 40 movsx edx, WORD PTR [rax+64] 000a3 44 0f bf 70 50 movsx r14d, WORD PTR [rax+80] 000a8 0f bf 70 30 movsx esi, WORD PTR [rax+48] 000ac 44 0f bf 68 e0 movsx r13d, WORD PTR [rax-32] 000b1 42 8d 0c 0a lea ecx, DWORD PTR [rdx+r9] 000b5 44 69 c1 a9 08 00 00 imul r8d, ecx, 2217 ; 000008a9H 000bc 69 ca 8f 1d 00 00 imul ecx, edx, 7567 ; 00001d8fH 000c2 41 69 d1 3f 0c 00 00 imul edx, r9d, 3135 ; 00000c3fH 000c9 44 8d 0c 1e lea r9d, DWORD PTR [rsi+rbx] 000cd 45 8b d0 mov r10d, r8d 000d0 44 2b d1 sub r10d, ecx 000d3 0f bf 48 20 movsx ecx, WORD PTR [rax+32] 000d7 41 03 d0 add edx, r8d 000da 46 8d 04 29 lea r8d, DWORD PTR [rcx+r13] 000de 44 2b e9 sub r13d, ecx 000e1 41 c1 e0 0c shl r8d, 12 000e5 41 c1 e5 0c shl r13d, 12 000e9 45 8d 3c 10 lea r15d, DWORD PTR [r8+rdx] 000ed 44 2b c2 sub r8d, edx 000f0 47 8d 24 2a lea r12d, DWORD PTR [r10+r13] 000f4 44 89 04 24 mov DWORD PTR $T9[rsp], r8d 000f8 45 2b ea sub r13d, r10d 000fb 47 8d 04 1e lea r8d, DWORD PTR [r14+r11] 000ff 43 8d 0c 01 lea ecx, DWORD PTR [r9+r8] 00103 44 8b d3 mov r10d, ebx 00106 69 f9 d0 12 00 00 imul edi, ecx, 4816 ; 000012d0H ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; 0010c 41 81 c7 00 02 00 00 add r15d, 512 ; 00000200H 00113 41 8d 0c 1e lea ecx, DWORD PTR [r14+rbx] 00117 41 81 c4 00 02 00 00 add r12d, 512 ; 00000200H 0011e 69 d1 65 0e 00 00 imul edx, ecx, 3685 ; 00000e65H 00124 41 81 c5 00 02 00 00 add r13d, 512 ; 00000200H 0012b 42 8d 0c 1e lea ecx, DWORD PTR [rsi+r11] 0012f 8b df mov ebx, edi 00131 2b da sub ebx, edx 00133 69 d1 01 29 00 00 imul edx, ecx, 10497 ; 00002901H 00139 41 69 c9 c3 f9 ff ff imul ecx, r9d, -1597 ; fffffffffffff9c3H 00140 45 69 cb 2a 31 00 00 imul r9d, r11d, 12586 ; 0000312aH 00147 45 69 de c7 04 00 00 imul r11d, r14d, 1223 ; 000004c7H 0014e 2b fa sub edi, edx 00150 41 69 d0 9e e0 ff ff imul edx, r8d, -8034 ; ffffffffffffe09eH 00157 45 69 c2 05 18 00 00 imul r8d, r10d, 6149 ; 00001805H 0015e 44 69 d6 da 20 00 00 imul r10d, esi, 8410 ; 000020daH 00165 44 03 db add r11d, ebx 00168 44 03 ca add r9d, edx 0016b 44 03 da add r11d, edx 0016e 8b 14 24 mov edx, DWORD PTR $T9[rsp] 00171 44 03 c1 add r8d, ecx 00174 44 03 d1 add r10d, ecx 00177 44 03 c3 add r8d, ebx 0017a 44 03 cf add r9d, edi 0017d 44 03 d7 add r10d, edi 00180 81 c2 00 02 00 00 add edx, 512 ; 00000200H ; 1962 : v[0] = (x0 + t3) >> 10; 00186 43 8d 0c 07 lea ecx, DWORD PTR [r15+r8] ; 1963 : v[56] = (x0 - t3) >> 10; 0018a 45 2b f8 sub r15d, r8d 0018d c1 f9 0a sar ecx, 10 00190 89 4d e0 mov DWORD PTR [rbp-32], ecx ; 1964 : v[8] = (x1 + t2) >> 10; 00193 43 8d 0c 0c lea ecx, DWORD PTR [r12+r9] 00197 c1 f9 0a sar ecx, 10 ; 1965 : v[48] = (x1 - t2) >> 10; 0019a 45 2b e1 sub r12d, r9d 0019d 89 4d 00 mov DWORD PTR [rbp], ecx ; 1966 : v[16] = (x2 + t1) >> 10; 001a0 43 8d 0c 2a lea ecx, DWORD PTR [r10+r13] 001a4 c1 f9 0a sar ecx, 10 ; 1967 : v[40] = (x2 - t1) >> 10; 001a7 45 2b ea sub r13d, r10d 001aa 89 4d 20 mov DWORD PTR [rbp+32], ecx ; 1968 : v[24] = (x3 + t0) >> 10; 001ad 42 8d 0c 1a lea ecx, DWORD PTR [rdx+r11] 001b1 41 c1 ff 0a sar r15d, 10 ; 1969 : v[32] = (x3 - t0) >> 10; 001b5 41 2b d3 sub edx, r11d 001b8 41 c1 fc 0a sar r12d, 10 001bc c1 f9 0a sar ecx, 10 001bf 41 c1 fd 0a sar r13d, 10 001c3 c1 fa 0a sar edx, 10 001c6 44 89 bd c0 00 00 00 mov DWORD PTR [rbp+192], r15d 001cd 44 89 a5 a0 00 00 00 mov DWORD PTR [rbp+160], r12d $LN2@stbi__idct: ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { 001d4 89 55 60 mov DWORD PTR [rbp+96], edx 001d7 44 89 ad 80 00 00 00 mov DWORD PTR [rbp+128], r13d 001de 89 4d 40 mov DWORD PTR [rbp+64], ecx 001e1 0f bf 58 f2 movsx ebx, WORD PTR [rax-14] 001e5 66 85 db test bx, bx 001e8 75 4a jne SHORT $LN56@stbi__idct 001ea 66 39 58 02 cmp WORD PTR [rax+2], bx 001ee 75 44 jne SHORT $LN56@stbi__idct 001f0 66 39 58 12 cmp WORD PTR [rax+18], bx 001f4 75 3e jne SHORT $LN56@stbi__idct 001f6 66 39 58 22 cmp WORD PTR [rax+34], bx 001fa 75 38 jne SHORT $LN56@stbi__idct 001fc 66 39 58 32 cmp WORD PTR [rax+50], bx 00200 75 32 jne SHORT $LN56@stbi__idct 00202 66 39 58 42 cmp WORD PTR [rax+66], bx 00206 75 2c jne SHORT $LN56@stbi__idct 00208 66 39 58 52 cmp WORD PTR [rax+82], bx 0020c 75 26 jne SHORT $LN56@stbi__idct ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; 0020e 0f bf 48 e2 movsx ecx, WORD PTR [rax-30] 00212 c1 e1 02 shl ecx, 2 ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; 00215 89 8d c4 00 00 00 mov DWORD PTR [rbp+196], ecx 0021b 44 8b e9 mov r13d, ecx 0021e 89 8d a4 00 00 00 mov DWORD PTR [rbp+164], ecx 00224 8b d1 mov edx, ecx 00226 89 4d 24 mov DWORD PTR [rbp+36], ecx 00229 89 4d 04 mov DWORD PTR [rbp+4], ecx 0022c 89 4d e4 mov DWORD PTR [rbp-28], ecx ; 1956 : } 0022f e9 3f 01 00 00 jmp $LN57@stbi__idct $LN56@stbi__idct: ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) 00234 44 0f bf 58 12 movsx r11d, WORD PTR [rax+18] 00239 44 0f bf 48 02 movsx r9d, WORD PTR [rax+2] 0023e 0f bf 50 42 movsx edx, WORD PTR [rax+66] 00242 44 0f bf 70 52 movsx r14d, WORD PTR [rax+82] 00247 0f bf 70 32 movsx esi, WORD PTR [rax+50] 0024b 44 0f bf 68 e2 movsx r13d, WORD PTR [rax-30] 00250 42 8d 0c 0a lea ecx, DWORD PTR [rdx+r9] 00254 44 69 c1 a9 08 00 00 imul r8d, ecx, 2217 ; 000008a9H 0025b 69 ca 8f 1d 00 00 imul ecx, edx, 7567 ; 00001d8fH 00261 41 69 d1 3f 0c 00 00 imul edx, r9d, 3135 ; 00000c3fH 00268 44 8d 0c 1e lea r9d, DWORD PTR [rsi+rbx] 0026c 45 8b d0 mov r10d, r8d 0026f 44 2b d1 sub r10d, ecx 00272 0f bf 48 22 movsx ecx, WORD PTR [rax+34] 00276 41 03 d0 add edx, r8d 00279 46 8d 04 29 lea r8d, DWORD PTR [rcx+r13] 0027d 44 2b e9 sub r13d, ecx 00280 41 c1 e0 0c shl r8d, 12 00284 41 c1 e5 0c shl r13d, 12 00288 45 8d 3c 10 lea r15d, DWORD PTR [r8+rdx] 0028c 44 2b c2 sub r8d, edx 0028f 47 8d 24 2a lea r12d, DWORD PTR [r10+r13] 00293 44 89 04 24 mov DWORD PTR $T10[rsp], r8d 00297 45 2b ea sub r13d, r10d 0029a 47 8d 04 1e lea r8d, DWORD PTR [r14+r11] 0029e 43 8d 0c 01 lea ecx, DWORD PTR [r9+r8] 002a2 44 8b d3 mov r10d, ebx 002a5 69 f9 d0 12 00 00 imul edi, ecx, 4816 ; 000012d0H ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; 002ab 41 81 c7 00 02 00 00 add r15d, 512 ; 00000200H 002b2 41 8d 0c 1e lea ecx, DWORD PTR [r14+rbx] 002b6 41 81 c4 00 02 00 00 add r12d, 512 ; 00000200H 002bd 69 d1 65 0e 00 00 imul edx, ecx, 3685 ; 00000e65H 002c3 41 81 c5 00 02 00 00 add r13d, 512 ; 00000200H 002ca 42 8d 0c 1e lea ecx, DWORD PTR [rsi+r11] 002ce 8b df mov ebx, edi 002d0 2b da sub ebx, edx 002d2 69 d1 01 29 00 00 imul edx, ecx, 10497 ; 00002901H 002d8 41 69 c9 c3 f9 ff ff imul ecx, r9d, -1597 ; fffffffffffff9c3H 002df 45 69 cb 2a 31 00 00 imul r9d, r11d, 12586 ; 0000312aH 002e6 45 69 de c7 04 00 00 imul r11d, r14d, 1223 ; 000004c7H 002ed 2b fa sub edi, edx 002ef 41 69 d0 9e e0 ff ff imul edx, r8d, -8034 ; ffffffffffffe09eH 002f6 45 69 c2 05 18 00 00 imul r8d, r10d, 6149 ; 00001805H 002fd 44 69 d6 da 20 00 00 imul r10d, esi, 8410 ; 000020daH 00304 44 03 db add r11d, ebx 00307 44 03 ca add r9d, edx 0030a 44 03 da add r11d, edx 0030d 8b 14 24 mov edx, DWORD PTR $T10[rsp] 00310 44 03 c1 add r8d, ecx 00313 44 03 d1 add r10d, ecx 00316 44 03 c3 add r8d, ebx 00319 44 03 cf add r9d, edi 0031c 44 03 d7 add r10d, edi 0031f 81 c2 00 02 00 00 add edx, 512 ; 00000200H ; 1962 : v[0] = (x0 + t3) >> 10; 00325 43 8d 0c 07 lea ecx, DWORD PTR [r15+r8] ; 1963 : v[56] = (x0 - t3) >> 10; 00329 45 2b f8 sub r15d, r8d 0032c c1 f9 0a sar ecx, 10 0032f 89 4d e4 mov DWORD PTR [rbp-28], ecx ; 1964 : v[8] = (x1 + t2) >> 10; 00332 43 8d 0c 0c lea ecx, DWORD PTR [r12+r9] 00336 c1 f9 0a sar ecx, 10 ; 1965 : v[48] = (x1 - t2) >> 10; 00339 45 2b e1 sub r12d, r9d 0033c 89 4d 04 mov DWORD PTR [rbp+4], ecx ; 1966 : v[16] = (x2 + t1) >> 10; 0033f 43 8d 0c 2a lea ecx, DWORD PTR [r10+r13] 00343 c1 f9 0a sar ecx, 10 ; 1967 : v[40] = (x2 - t1) >> 10; 00346 45 2b ea sub r13d, r10d 00349 89 4d 24 mov DWORD PTR [rbp+36], ecx ; 1968 : v[24] = (x3 + t0) >> 10; 0034c 42 8d 0c 1a lea ecx, DWORD PTR [rdx+r11] 00350 41 c1 ff 0a sar r15d, 10 ; 1969 : v[32] = (x3 - t0) >> 10; 00354 41 2b d3 sub edx, r11d 00357 41 c1 fc 0a sar r12d, 10 0035b c1 f9 0a sar ecx, 10 0035e 41 c1 fd 0a sar r13d, 10 00362 c1 fa 0a sar edx, 10 00365 44 89 bd c4 00 00 00 mov DWORD PTR [rbp+196], r15d 0036c 44 89 a5 a4 00 00 00 mov DWORD PTR [rbp+164], r12d $LN57@stbi__idct: 00373 89 55 64 mov DWORD PTR [rbp+100], edx 00376 48 83 c0 04 add rax, 4 0037a 44 89 ad 84 00 00 00 mov DWORD PTR [rbp+132], r13d 00381 89 4d 44 mov DWORD PTR [rbp+68], ecx 00384 48 83 c5 08 add rbp, 8 00388 48 83 6c 24 08 01 sub QWORD PTR tv2514[rsp], 1 0038e 0f 85 b0 fc ff ff jne $LL4@stbi__idct ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { 00394 4c 8b 6c 24 10 mov r13, QWORD PTR out$GSCopy$1$[rsp] 00399 4c 8d 5c 24 38 lea r11, QWORD PTR val$[rsp+24] 0039e 4c 89 5c 24 08 mov QWORD PTR tv2499[rsp], r11 003a3 49 ff c5 inc r13 003a6 48 c7 44 24 10 08 00 00 00 mov QWORD PTR tv2511[rsp], 8 003af 90 npad 1 $LL7@stbi__idct: ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) 003b0 45 8b 43 f0 mov r8d, DWORD PTR [r11-16] 003b4 41 8b 0b mov ecx, DWORD PTR [r11] 003b7 41 8b 73 04 mov esi, DWORD PTR [r11+4] 003bb 41 8b 7b fc mov edi, DWORD PTR [r11-4] 003bf 45 8b 53 f4 mov r10d, DWORD PTR [r11-12] 003c3 45 8b 73 e8 mov r14d, DWORD PTR [r11-24] 003c7 42 8d 04 01 lea eax, DWORD PTR [rcx+r8] 003cb 69 d0 a9 08 00 00 imul edx, eax, 2217 ; 000008a9H 003d1 69 c1 8f 1d 00 00 imul eax, ecx, 7567 ; 00001d8fH 003d7 41 69 c8 3f 0c 00 00 imul ecx, r8d, 3135 ; 00000c3fH 003de 44 8b ca mov r9d, edx 003e1 44 2b c8 sub r9d, eax 003e4 41 8b 43 f8 mov eax, DWORD PTR [r11-8] 003e8 03 ca add ecx, edx 003ea 42 8d 14 16 lea edx, DWORD PTR [rsi+r10] 003ee 46 8d 3c 30 lea r15d, DWORD PTR [rax+r14] 003f2 44 2b f0 sub r14d, eax 003f5 41 c1 e6 0c shl r14d, 12 003f9 41 c1 e7 0c shl r15d, 12 003fd 47 8d 24 0e lea r12d, DWORD PTR [r14+r9] 00401 45 2b f1 sub r14d, r9d 00404 45 8b 4b ec mov r9d, DWORD PTR [r11-20] 00408 41 8d 2c 0f lea ebp, DWORD PTR [r15+rcx] 0040c 44 2b f9 sub r15d, ecx ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); 0040f 81 c5 00 00 01 01 add ebp, 16842752 ; 01010000H ; 1983 : x1 += 65536 + (128 << 17); 00415 41 81 c4 00 00 01 01 add r12d, 16842752 ; 01010000H ; 1984 : x2 += 65536 + (128 << 17); 0041c 41 81 c6 00 00 01 01 add r14d, 16842752 ; 01010000H ; 1985 : x3 += 65536 + (128 << 17); 00423 41 81 c7 00 00 01 01 add r15d, 16842752 ; 01010000H 0042a 46 8d 04 0f lea r8d, DWORD PTR [rdi+r9] 0042e 41 8d 04 10 lea eax, DWORD PTR [r8+rdx] 00432 69 d8 d0 12 00 00 imul ebx, eax, 4816 ; 000012d0H 00438 42 8d 04 0e lea eax, DWORD PTR [rsi+r9] 0043c 69 c8 65 0e 00 00 imul ecx, eax, 3685 ; 00000e65H 00442 42 8d 04 17 lea eax, DWORD PTR [rdi+r10] 00446 44 8b db mov r11d, ebx 00449 44 2b d9 sub r11d, ecx 0044c 69 c8 01 29 00 00 imul ecx, eax, 10497 ; 00002901H 00452 41 69 c0 c3 f9 ff ff imul eax, r8d, -1597 ; fffffffffffff9c3H 00459 44 69 c7 da 20 00 00 imul r8d, edi, 8410 ; 000020daH 00460 2b d9 sub ebx, ecx 00462 69 ca 9e e0 ff ff imul ecx, edx, -8034 ; ffffffffffffe09eH 00468 41 69 d1 05 18 00 00 imul edx, r9d, 6149 ; 00001805H 0046f 44 03 c0 add r8d, eax 00472 44 69 ce c7 04 00 00 imul r9d, esi, 1223 ; 000004c7H 00479 44 03 c3 add r8d, ebx 0047c 03 d0 add edx, eax 0047e 41 03 d3 add edx, r11d 00481 45 03 cb add r9d, r11d 00484 89 14 24 mov DWORD PTR t3$3$[rsp], edx 00487 44 03 c9 add r9d, ecx 0048a 41 69 d2 2a 31 00 00 imul edx, r10d, 12586 ; 0000312aH 00491 03 d1 add edx, ecx ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); 00493 8b 0c 24 mov ecx, DWORD PTR t3$3$[rsp] 00496 03 d3 add edx, ebx 00498 8d 04 29 lea eax, DWORD PTR [rcx+rbp] 0049b c1 f8 11 sar eax, 17 ; 1891 : if ((unsigned int)x > 255) { 0049e 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 004a3 76 11 jbe SHORT $LN14@stbi__idct ; 1892 : if (x < 0) return 0; 004a5 85 c0 test eax, eax 004a7 79 04 jns SHORT $LN13@stbi__idct 004a9 32 c0 xor al, al 004ab eb 09 jmp SHORT $LN14@stbi__idct $LN13@stbi__idct: ; 1893 : if (x > 255) return 255; 004ad 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 004b2 7e 02 jle SHORT $LN14@stbi__idct 004b4 b0 ff mov al, 255 ; 000000ffH $LN14@stbi__idct: ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); 004b6 2b e9 sub ebp, ecx 004b8 41 88 45 ff mov BYTE PTR [r13-1], al 004bc c1 fd 11 sar ebp, 17 ; 1891 : if ((unsigned int)x > 255) { 004bf 81 fd ff 00 00 00 cmp ebp, 255 ; 000000ffH 004c5 76 14 jbe SHORT $LN19@stbi__idct ; 1892 : if (x < 0) return 0; 004c7 85 ed test ebp, ebp 004c9 79 05 jns SHORT $LN18@stbi__idct 004cb 40 32 ed xor bpl, bpl 004ce eb 0b jmp SHORT $LN19@stbi__idct $LN18@stbi__idct: ; 1893 : if (x > 255) return 255; 004d0 81 fd ff 00 00 00 cmp ebp, 255 ; 000000ffH 004d6 7e 03 jle SHORT $LN19@stbi__idct 004d8 40 b5 ff mov bpl, 255 ; 000000ffH $LN19@stbi__idct: ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); 004db 41 8d 04 14 lea eax, DWORD PTR [r12+rdx] 004df 41 88 6d 06 mov BYTE PTR [r13+6], bpl 004e3 c1 f8 11 sar eax, 17 ; 1891 : if ((unsigned int)x > 255) { 004e6 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 004eb 76 11 jbe SHORT $LN24@stbi__idct ; 1892 : if (x < 0) return 0; 004ed 85 c0 test eax, eax 004ef 79 04 jns SHORT $LN23@stbi__idct 004f1 32 c0 xor al, al 004f3 eb 09 jmp SHORT $LN24@stbi__idct $LN23@stbi__idct: ; 1893 : if (x > 255) return 255; 004f5 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 004fa 7e 02 jle SHORT $LN24@stbi__idct 004fc b0 ff mov al, 255 ; 000000ffH $LN24@stbi__idct: ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); 004fe 44 2b e2 sub r12d, edx 00501 41 88 45 00 mov BYTE PTR [r13], al 00505 41 c1 fc 11 sar r12d, 17 ; 1891 : if ((unsigned int)x > 255) { 00509 41 81 fc ff 00 00 00 cmp r12d, 255 ; 000000ffH 00510 76 16 jbe SHORT $LN29@stbi__idct ; 1892 : if (x < 0) return 0; 00512 45 85 e4 test r12d, r12d 00515 79 05 jns SHORT $LN28@stbi__idct 00517 45 32 e4 xor r12b, r12b 0051a eb 0c jmp SHORT $LN29@stbi__idct $LN28@stbi__idct: ; 1893 : if (x > 255) return 255; 0051c 41 81 fc ff 00 00 00 cmp r12d, 255 ; 000000ffH 00523 7e 03 jle SHORT $LN29@stbi__idct 00525 41 b4 ff mov r12b, 255 ; 000000ffH $LN29@stbi__idct: ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); 00528 43 8d 04 06 lea eax, DWORD PTR [r14+r8] 0052c 45 88 65 05 mov BYTE PTR [r13+5], r12b 00530 c1 f8 11 sar eax, 17 ; 1891 : if ((unsigned int)x > 255) { 00533 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00538 76 11 jbe SHORT $LN34@stbi__idct ; 1892 : if (x < 0) return 0; 0053a 85 c0 test eax, eax 0053c 79 04 jns SHORT $LN33@stbi__idct 0053e 32 c0 xor al, al 00540 eb 09 jmp SHORT $LN34@stbi__idct $LN33@stbi__idct: ; 1893 : if (x > 255) return 255; 00542 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00547 7e 02 jle SHORT $LN34@stbi__idct 00549 b0 ff mov al, 255 ; 000000ffH $LN34@stbi__idct: ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); 0054b 45 2b f0 sub r14d, r8d 0054e 41 88 45 01 mov BYTE PTR [r13+1], al 00552 41 c1 fe 11 sar r14d, 17 ; 1891 : if ((unsigned int)x > 255) { 00556 41 81 fe ff 00 00 00 cmp r14d, 255 ; 000000ffH 0055d 76 16 jbe SHORT $LN39@stbi__idct ; 1892 : if (x < 0) return 0; 0055f 45 85 f6 test r14d, r14d 00562 79 05 jns SHORT $LN38@stbi__idct 00564 45 32 f6 xor r14b, r14b 00567 eb 0c jmp SHORT $LN39@stbi__idct $LN38@stbi__idct: ; 1893 : if (x > 255) return 255; 00569 41 81 fe ff 00 00 00 cmp r14d, 255 ; 000000ffH 00570 7e 03 jle SHORT $LN39@stbi__idct 00572 41 b6 ff mov r14b, 255 ; 000000ffH $LN39@stbi__idct: ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); 00575 43 8d 04 0f lea eax, DWORD PTR [r15+r9] 00579 45 88 75 04 mov BYTE PTR [r13+4], r14b 0057d c1 f8 11 sar eax, 17 ; 1891 : if ((unsigned int)x > 255) { 00580 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00585 76 11 jbe SHORT $LN44@stbi__idct ; 1892 : if (x < 0) return 0; 00587 85 c0 test eax, eax 00589 79 04 jns SHORT $LN43@stbi__idct 0058b 32 c0 xor al, al 0058d eb 09 jmp SHORT $LN44@stbi__idct $LN43@stbi__idct: ; 1893 : if (x > 255) return 255; 0058f 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00594 7e 02 jle SHORT $LN44@stbi__idct 00596 b0 ff mov al, 255 ; 000000ffH $LN44@stbi__idct: ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); 00598 45 2b f9 sub r15d, r9d 0059b 41 88 45 02 mov BYTE PTR [r13+2], al 0059f 41 c1 ff 11 sar r15d, 17 ; 1891 : if ((unsigned int)x > 255) { 005a3 41 81 ff ff 00 00 00 cmp r15d, 255 ; 000000ffH 005aa 76 16 jbe SHORT $LN49@stbi__idct ; 1892 : if (x < 0) return 0; 005ac 45 85 ff test r15d, r15d 005af 79 05 jns SHORT $LN48@stbi__idct 005b1 45 32 ff xor r15b, r15b 005b4 eb 0c jmp SHORT $LN49@stbi__idct $LN48@stbi__idct: ; 1893 : if (x > 255) return 255; 005b6 41 81 ff ff 00 00 00 cmp r15d, 255 ; 000000ffH 005bd 7e 03 jle SHORT $LN49@stbi__idct 005bf 41 b7 ff mov r15b, 255 ; 000000ffH $LN49@stbi__idct: ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { 005c2 4c 8b 5c 24 08 mov r11, QWORD PTR tv2499[rsp] 005c7 48 63 4c 24 18 movsxd rcx, DWORD PTR out_stride$GSCopy$1$[rsp] 005cc 49 83 c3 20 add r11, 32 ; 00000020H ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); 005d0 45 88 7d 03 mov BYTE PTR [r13+3], r15b 005d4 4c 03 e9 add r13, rcx 005d7 48 83 6c 24 10 01 sub QWORD PTR tv2511[rsp], 1 005dd 4c 89 5c 24 08 mov QWORD PTR tv2499[rsp], r11 005e2 0f 85 c8 fd ff ff jne $LL7@stbi__idct ; 1996 : } ; 1997 : } 005e8 48 8b 8c 24 20 01 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 005f0 48 33 cc xor rcx, rsp 005f3 e8 00 00 00 00 call __security_check_cookie 005f8 48 8b 9c 24 80 01 00 00 mov rbx, QWORD PTR [rsp+384] 00600 48 81 c4 30 01 00 00 add rsp, 304 ; 00000130H 00607 41 5f pop r15 00609 41 5e pop r14 0060b 41 5d pop r13 0060d 41 5c pop r12 0060f 5f pop rdi 00610 5e pop rsi 00611 5d pop rbp 00612 c3 ret 0 stbi__idct_block ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__idct_simd _TEXT SEGMENT y5o_h$1$ = 0 abiased_h$1$ = 16 abiased_h$1$ = 16 p2$1$ = 32 t3e_l$1$ = 32 abiased_l$1$ = 48 row4$2$ = 48 x7_h$1$ = 64 t3e_h$1$ = 64 x6_h$1$ = 80 row5$2$ = 80 x6_l$1$ = 96 t2e_h$1$ = 96 x7_l$1$ = 112 t2e_l$1$ = 112 out$ = 304 out_stride$ = 312 data$ = 320 stbi__idct_simd PROC ; COMDAT ; 2004 : { 00000 4c 8b dc mov r11, rsp 00003 48 81 ec 28 01 00 00 sub rsp, 296 ; 00000128H ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); 0000a f3 41 0f 6f 58 10 movdqu xmm3, XMMWORD PTR [r8+16] 00010 0f 57 c9 xorps xmm1, xmm1 ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); 00013 f3 41 0f 6f 68 50 movdqu xmm5, XMMWORD PTR [r8+80] 00019 f3 41 0f 6f 60 30 movdqu xmm4, XMMWORD PTR [r8+48] 0001f f3 41 0f 6f 10 movdqu xmm2, XMMWORD PTR [r8] 00024 41 0f 29 73 e8 movaps XMMWORD PTR [r11-24], xmm6 00029 41 0f 29 7b d8 movaps XMMWORD PTR [r11-40], xmm7 0002e f3 41 0f 6f 78 20 movdqu xmm7, XMMWORD PTR [r8+32] 00034 45 0f 29 43 c8 movaps XMMWORD PTR [r11-56], xmm8 ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); 00039 66 0f 6f f7 movdqa xmm6, xmm7 0003d 66 41 0f 69 78 60 punpckhwd xmm7, XMMWORD PTR [r8+96] 00043 66 41 0f 61 70 60 punpcklwd xmm6, XMMWORD PTR [r8+96] 00049 66 0f 6f c7 movdqa xmm0, xmm7 0004d 66 0f f5 05 00 00 00 00 pmaddwd xmm0, XMMWORD PTR __xmm@eb1a08a9eb1a08a9eb1a08a9eb1a08a9 00055 66 0f f5 3d 00 00 00 00 pmaddwd xmm7, XMMWORD PTR __xmm@08a914e808a914e808a914e808a914e8 0005d f3 45 0f 6f 40 70 movdqu xmm8, XMMWORD PTR [r8+112] 00063 45 0f 29 4b b8 movaps XMMWORD PTR [r11-72], xmm9 00068 45 0f 29 53 a8 movaps XMMWORD PTR [r11-88], xmm10 0006d 45 0f 29 5b 98 movaps XMMWORD PTR [r11-104], xmm11 00072 45 0f 29 63 88 movaps XMMWORD PTR [r11-120], xmm12 00077 45 0f 29 ab 78 ff ff ff movaps XMMWORD PTR [r11-136], xmm13 0007f 45 0f 29 b3 68 ff ff ff movaps XMMWORD PTR [r11-152], xmm14 00087 45 0f 29 bb 58 ff ff ff movaps XMMWORD PTR [r11-168], xmm15 0008f 66 45 0f 6f d0 movdqa xmm10, xmm8 00094 66 0f 7f 44 24 60 movdqa XMMWORD PTR t2e_h$1$[rsp], xmm0 0009a 66 44 0f 6f f6 movdqa xmm14, xmm6 0009f 66 0f f5 35 00 00 00 00 pmaddwd xmm6, XMMWORD PTR __xmm@08a914e808a914e808a914e808a914e8 000a7 66 45 0f 6f d8 movdqa xmm11, xmm8 000ac f3 41 0f 6f 40 40 movdqu xmm0, XMMWORD PTR [r8+64] 000b2 66 44 0f fd c3 paddw xmm8, xmm3 000b7 66 44 0f f5 35 00 00 00 00 pmaddwd xmm14, XMMWORD PTR __xmm@eb1a08a9eb1a08a9eb1a08a9eb1a08a9 000c0 66 0f fd c2 paddw xmm0, xmm2 000c4 66 41 0f f9 50 40 psubw xmm2, XMMWORD PTR [r8+64] 000ca 45 0f 57 ff xorps xmm15, xmm15 000ce 66 0f 61 c8 punpcklwd xmm1, xmm0 000d2 66 0f 72 e1 04 psrad xmm1, 4 000d7 66 0f 7f 4c 24 30 movdqa XMMWORD PTR row4$2$[rsp], xmm1 000dd 0f 57 c9 xorps xmm1, xmm1 000e0 66 0f 69 c8 punpckhwd xmm1, xmm0 000e4 0f 57 c0 xorps xmm0, xmm0 000e7 66 0f 61 c2 punpcklwd xmm0, xmm2 000eb 66 0f 72 e0 04 psrad xmm0, 4 000f0 66 0f 7f 44 24 50 movdqa XMMWORD PTR row5$2$[rsp], xmm0 000f6 66 41 0f 6f c0 movdqa xmm0, xmm8 000fb 66 0f 72 e1 04 psrad xmm1, 4 00100 66 44 0f 61 d4 punpcklwd xmm10, xmm4 00105 66 44 0f 69 fa punpckhwd xmm15, xmm2 0010a 66 45 0f 6f ea movdqa xmm13, xmm10 0010f 66 44 0f f5 2d 00 00 00 00 pmaddwd xmm13, XMMWORD PTR __xmm@e09ee565e09ee565e09ee565e09ee565 00118 66 44 0f f5 15 00 00 00 00 pmaddwd xmm10, XMMWORD PTR __xmm@11c8e09e11c8e09e11c8e09e11c8e09e 00121 66 0f 7f 74 24 20 movdqa XMMWORD PTR t3e_l$1$[rsp], xmm6 00127 66 0f 6f f5 movdqa xmm6, xmm5 0012b 66 0f 61 f3 punpcklwd xmm6, xmm3 0012f 66 0f 7f 7c 24 40 movdqa XMMWORD PTR t3e_h$1$[rsp], xmm7 00135 66 44 0f 6f ce movdqa xmm9, xmm6 0013a 66 44 0f f5 0d 00 00 00 00 pmaddwd xmm9, XMMWORD PTR __xmm@f9c31a9df9c31a9df9c31a9df9c31a9d 00143 66 0f 6f fd movdqa xmm7, xmm5 00147 66 0f 69 fb punpckhwd xmm7, xmm3 0014b 66 0f fd ec paddw xmm5, xmm4 0014f 66 0f 61 c5 punpcklwd xmm0, xmm5 00153 66 0f 6f df movdqa xmm3, xmm7 00157 66 0f f5 1d 00 00 00 00 pmaddwd xmm3, XMMWORD PTR __xmm@f9c31a9df9c31a9df9c31a9df9c31a9d 0015f 66 44 0f 69 dc punpckhwd xmm11, xmm4 00164 66 44 0f 69 c5 punpckhwd xmm8, xmm5 00169 66 45 0f 6f e3 movdqa xmm12, xmm11 0016e 66 44 0f f5 25 00 00 00 00 pmaddwd xmm12, XMMWORD PTR __xmm@e09ee565e09ee565e09ee565e09ee565 00177 66 41 0f 6f d0 movdqa xmm2, xmm8 0017c 66 0f f5 15 00 00 00 00 pmaddwd xmm2, XMMWORD PTR __xmm@12d0046b12d0046b12d0046b12d0046b 00184 66 44 0f f5 05 00 00 00 00 pmaddwd xmm8, XMMWORD PTR __xmm@e9cf12d0e9cf12d0e9cf12d0e9cf12d0 0018d 66 44 0f f5 1d 00 00 00 00 pmaddwd xmm11, XMMWORD PTR __xmm@11c8e09e11c8e09e11c8e09e11c8e09e 00196 66 0f 7f 4c 24 10 movdqa XMMWORD PTR abiased_h$1$[rsp], xmm1 0019c 66 0f 6f c8 movdqa xmm1, xmm0 001a0 66 0f f5 05 00 00 00 00 pmaddwd xmm0, XMMWORD PTR __xmm@e9cf12d0e9cf12d0e9cf12d0e9cf12d0 001a8 66 0f f5 0d 00 00 00 00 pmaddwd xmm1, XMMWORD PTR __xmm@12d0046b12d0046b12d0046b12d0046b 001b0 66 44 0f fe e2 paddd xmm12, xmm2 001b5 66 44 0f 7f 74 24 70 movdqa XMMWORD PTR t2e_l$1$[rsp], xmm14 001bc 66 41 0f fe d8 paddd xmm3, xmm8 001c1 66 41 0f 72 e7 04 psrad xmm15, 4 001c7 66 44 0f fe c8 paddd xmm9, xmm0 001cc 66 44 0f fe d0 paddd xmm10, xmm0 001d1 66 44 0f fe e9 paddd xmm13, xmm1 001d6 66 0f f5 35 00 00 00 00 pmaddwd xmm6, XMMWORD PTR __xmm@11c8f9c311c8f9c311c8f9c311c8f9c3 001de 66 45 0f fe d8 paddd xmm11, xmm8 001e3 66 0f 6f 25 00 00 00 00 movdqa xmm4, XMMWORD PTR __xmm@00000200000002000000020000000200 001eb 66 0f f5 3d 00 00 00 00 pmaddwd xmm7, XMMWORD PTR __xmm@11c8f9c311c8f9c311c8f9c311c8f9c3 001f3 66 44 0f 6f 44 24 30 movdqa xmm8, XMMWORD PTR row4$2$[rsp] 001fa 66 44 0f fe 44 24 20 paddd xmm8, XMMWORD PTR t3e_l$1$[rsp] 00201 66 0f fe f1 paddd xmm6, xmm1 00205 66 44 0f fe c4 paddd xmm8, xmm4 0020a 66 0f 6f 4c 24 10 movdqa xmm1, XMMWORD PTR abiased_h$1$[rsp] 00210 66 0f fe 4c 24 40 paddd xmm1, XMMWORD PTR t3e_h$1$[rsp] 00216 66 0f fe fa paddd xmm7, xmm2 0021a 66 0f fe cc paddd xmm1, xmm4 0021e 66 41 0f 6f d0 movdqa xmm2, xmm8 00223 66 0f fe d6 paddd xmm2, xmm6 00227 66 0f 6f c1 movdqa xmm0, xmm1 0022b 66 0f fa cf psubd xmm1, xmm7 0022f 66 0f 72 e2 0a psrad xmm2, 10 00234 66 0f fe c7 paddd xmm0, xmm7 00238 66 0f 72 e1 0a psrad xmm1, 10 0023d 66 0f 72 e0 0a psrad xmm0, 10 00242 66 44 0f fa c6 psubd xmm8, xmm6 00247 66 0f 6f 74 24 50 movdqa xmm6, XMMWORD PTR row5$2$[rsp] 0024d 66 0f 6b d0 packssdw xmm2, xmm0 00251 66 0f 6f ee movdqa xmm5, xmm6 00255 66 0f fa 74 24 70 psubd xmm6, XMMWORD PTR t2e_l$1$[rsp] 0025b 66 41 0f fe ee paddd xmm5, xmm14 00260 66 0f fe ec paddd xmm5, xmm4 00264 66 0f 7f 14 24 movdqa XMMWORD PTR y5o_h$1$[rsp], xmm2 00269 66 0f 6f 54 24 30 movdqa xmm2, XMMWORD PTR row4$2$[rsp] 0026f 66 0f fe f4 paddd xmm6, xmm4 00273 66 0f fa 54 24 20 psubd xmm2, XMMWORD PTR t3e_l$1$[rsp] 00279 66 44 0f 6f f5 movdqa xmm14, xmm5 0027e 66 0f fe 15 00 00 00 00 paddd xmm2, XMMWORD PTR __xmm@00000200000002000000020000000200 00286 66 45 0f fe f2 paddd xmm14, xmm10 0028b 66 41 0f fa ea psubd xmm5, xmm10 00290 66 41 0f 72 e0 0a psrad xmm8, 10 00296 66 44 0f 6b c1 packssdw xmm8, xmm1 0029b 66 41 0f 6f cf movdqa xmm1, xmm15 002a0 66 0f fe 4c 24 60 paddd xmm1, XMMWORD PTR t2e_h$1$[rsp] 002a6 66 44 0f fa 7c 24 60 psubd xmm15, XMMWORD PTR t2e_h$1$[rsp] 002ad 66 0f fe cc paddd xmm1, xmm4 002b1 66 0f 6f c1 movdqa xmm0, xmm1 002b5 66 41 0f 72 e6 0a psrad xmm14, 10 002bb 66 41 0f fe c3 paddd xmm0, xmm11 002c0 66 0f 72 e5 0a psrad xmm5, 10 002c5 66 0f 72 e0 0a psrad xmm0, 10 002ca 66 44 0f fe fc paddd xmm15, xmm4 002cf 66 44 0f 6b f0 packssdw xmm14, xmm0 002d4 66 41 0f fa cb psubd xmm1, xmm11 002d9 66 0f 72 e1 0a psrad xmm1, 10 002de 66 0f 6f e6 movdqa xmm4, xmm6 002e2 66 0f 6b e9 packssdw xmm5, xmm1 002e6 66 41 0f 6f c7 movdqa xmm0, xmm15 002eb 66 0f 6f 4c 24 10 movdqa xmm1, XMMWORD PTR abiased_h$1$[rsp] 002f1 66 0f fe c3 paddd xmm0, xmm3 002f5 66 0f fa 4c 24 40 psubd xmm1, XMMWORD PTR t3e_h$1$[rsp] 002fb 66 44 0f fa fb psubd xmm15, xmm3 00300 66 0f fe 0d 00 00 00 00 paddd xmm1, XMMWORD PTR __xmm@00000200000002000000020000000200 00308 66 0f 6f da movdqa xmm3, xmm2 0030c 66 0f 72 e0 0a psrad xmm0, 10 00311 66 41 0f fe e1 paddd xmm4, xmm9 00316 66 41 0f fe dd paddd xmm3, xmm13 0031b 66 0f 72 e4 0a psrad xmm4, 10 00320 66 0f 6b e0 packssdw xmm4, xmm0 00324 66 41 0f fa d5 psubd xmm2, xmm13 00329 66 0f 6f c1 movdqa xmm0, xmm1 0032d 66 0f 72 e3 0a psrad xmm3, 10 00332 66 41 0f fe c4 paddd xmm0, xmm12 00337 66 0f 72 e2 0a psrad xmm2, 10 0033c 66 0f 72 e0 0a psrad xmm0, 10 00341 66 41 0f fa f1 psubd xmm6, xmm9 00346 66 41 0f fa cc psubd xmm1, xmm12 0034b 66 0f 6b d8 packssdw xmm3, xmm0 ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); 0034f 66 0f 6f 04 24 movdqa xmm0, XMMWORD PTR y5o_h$1$[rsp] 00354 66 0f 72 e1 0a psrad xmm1, 10 00359 66 0f 6f f8 movdqa xmm7, xmm0 0035d 66 0f 72 e6 0a psrad xmm6, 10 00362 66 41 0f 72 e7 0a psrad xmm15, 10 00368 66 0f 6b d1 packssdw xmm2, xmm1 0036c 66 0f 61 fa punpcklwd xmm7, xmm2 00370 66 41 0f 6b f7 packssdw xmm6, xmm15 00375 66 0f 69 c2 punpckhwd xmm0, xmm2 ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); 00379 66 0f 6f cb movdqa xmm1, xmm3 0037d 66 0f 7f 04 24 movdqa XMMWORD PTR y5o_h$1$[rsp], xmm0 00382 66 41 0f 6f d6 movdqa xmm2, xmm14 00387 66 41 0f 61 c8 punpcklwd xmm1, xmm8 0038c 66 0f 6f c4 movdqa xmm0, xmm4 00390 66 0f 61 c5 punpcklwd xmm0, xmm5 00394 66 0f 61 d6 punpcklwd xmm2, xmm6 00398 66 41 0f 69 d8 punpckhwd xmm3, xmm8 ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); 0039d 66 44 0f 6f 04 24 movdqa xmm8, XMMWORD PTR y5o_h$1$[rsp] 003a3 66 44 0f 69 f6 punpckhwd xmm14, xmm6 003a8 66 0f 6f f7 movdqa xmm6, xmm7 003ac 66 0f 61 f0 punpcklwd xmm6, xmm0 003b0 66 0f 69 f8 punpckhwd xmm7, xmm0 003b4 66 0f 6f c2 movdqa xmm0, xmm2 003b8 66 0f 61 c1 punpcklwd xmm0, xmm1 ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); 003bc 66 44 0f 6f ff movdqa xmm15, xmm7 003c1 66 0f 69 d1 punpckhwd xmm2, xmm1 003c5 66 41 0f 6f ce movdqa xmm1, xmm14 003ca 66 0f 61 cb punpcklwd xmm1, xmm3 003ce 66 44 0f 69 f3 punpckhwd xmm14, xmm3 003d3 66 0f 6f de movdqa xmm3, xmm6 003d7 66 0f 61 d8 punpcklwd xmm3, xmm0 003db 66 0f 69 f0 punpckhwd xmm6, xmm0 003df 66 44 0f 61 fa punpcklwd xmm15, xmm2 003e4 66 0f 69 fa punpckhwd xmm7, xmm2 ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); 003e8 66 45 0f 6f ef movdqa xmm13, xmm15 003ed 66 0f 69 e5 punpckhwd xmm4, xmm5 003f1 66 41 0f 6f e8 movdqa xmm5, xmm8 003f6 66 44 0f 69 c4 punpckhwd xmm8, xmm4 003fb 66 0f 61 ec punpcklwd xmm5, xmm4 003ff 66 41 0f 6f c0 movdqa xmm0, xmm8 00404 66 41 0f 61 c6 punpcklwd xmm0, xmm14 00409 66 0f 6f d5 movdqa xmm2, xmm5 0040d 66 0f 61 d1 punpcklwd xmm2, xmm1 00411 66 44 0f 61 e8 punpcklwd xmm13, xmm0 00416 66 44 0f 69 f8 punpckhwd xmm15, xmm0 0041b 66 45 0f 6f cd movdqa xmm9, xmm13 00420 66 44 0f f5 0d 00 00 00 00 pmaddwd xmm9, XMMWORD PTR __xmm@eb1a08a9eb1a08a9eb1a08a9eb1a08a9 00429 66 0f 6f c2 movdqa xmm0, xmm2 0042d 66 44 0f f5 2d 00 00 00 00 pmaddwd xmm13, XMMWORD PTR __xmm@08a914e808a914e808a914e808a914e8 00436 66 0f fd c3 paddw xmm0, xmm3 0043a 66 0f 69 e9 punpckhwd xmm5, xmm1 0043e 66 0f f9 da psubw xmm3, xmm2 00442 66 45 0f 69 c6 punpckhwd xmm8, xmm14 00447 0f 57 c9 xorps xmm1, xmm1 0044a 66 0f 61 c8 punpcklwd xmm1, xmm0 0044e 0f 57 d2 xorps xmm2, xmm2 00451 66 0f 69 d3 punpckhwd xmm2, xmm3 00455 66 41 0f 6f e0 movdqa xmm4, xmm8 0045a 66 0f 72 e1 04 psrad xmm1, 4 0045f 45 0f 57 f6 xorps xmm14, xmm14 00463 66 44 0f 69 f0 punpckhwd xmm14, xmm0 00468 66 44 0f 6f dd movdqa xmm11, xmm5 0046d 0f 57 c0 xorps xmm0, xmm0 00470 66 0f 72 e2 04 psrad xmm2, 4 00475 66 0f 61 c3 punpcklwd xmm0, xmm3 00479 66 44 0f 6f e5 movdqa xmm12, xmm5 0047e 66 0f 72 e0 04 psrad xmm0, 4 00483 66 41 0f 6f d8 movdqa xmm3, xmm8 00488 66 0f 7f 44 24 30 movdqa XMMWORD PTR abiased_l$1$[rsp], xmm0 0048e 66 44 0f fd c6 paddw xmm8, xmm6 00493 66 41 0f 6f c0 movdqa xmm0, xmm8 00498 66 0f 7f 4c 24 20 movdqa XMMWORD PTR p2$1$[rsp], xmm1 0049e 66 0f fd ef paddw xmm5, xmm7 004a2 66 0f 7f 54 24 10 movdqa XMMWORD PTR abiased_h$1$[rsp], xmm2 004a8 66 0f 61 c5 punpcklwd xmm0, xmm5 004ac 66 45 0f 6f d7 movdqa xmm10, xmm15 004b1 66 44 0f f5 15 00 00 00 00 pmaddwd xmm10, XMMWORD PTR __xmm@eb1a08a9eb1a08a9eb1a08a9eb1a08a9 004ba 66 0f 6f c8 movdqa xmm1, xmm0 004be 66 0f f5 0d 00 00 00 00 pmaddwd xmm1, XMMWORD PTR __xmm@12d0046b12d0046b12d0046b12d0046b 004c6 66 44 0f f5 3d 00 00 00 00 pmaddwd xmm15, XMMWORD PTR __xmm@08a914e808a914e808a914e808a914e8 004cf 66 0f f5 05 00 00 00 00 pmaddwd xmm0, XMMWORD PTR __xmm@e9cf12d0e9cf12d0e9cf12d0e9cf12d0 004d7 66 44 0f 69 c5 punpckhwd xmm8, xmm5 004dc 66 41 0f 6f d0 movdqa xmm2, xmm8 004e1 66 41 0f 72 e6 04 psrad xmm14, 4 004e7 66 0f f5 15 00 00 00 00 pmaddwd xmm2, XMMWORD PTR __xmm@12d0046b12d0046b12d0046b12d0046b 004ef 66 0f 61 df punpcklwd xmm3, xmm7 004f3 66 0f 69 e7 punpckhwd xmm4, xmm7 004f7 66 44 0f 61 de punpcklwd xmm11, xmm6 004fc 66 44 0f 69 e6 punpckhwd xmm12, xmm6 00501 66 44 0f f5 05 00 00 00 00 pmaddwd xmm8, XMMWORD PTR __xmm@e9cf12d0e9cf12d0e9cf12d0e9cf12d0 0050a 66 0f 6f ec movdqa xmm5, xmm4 0050e 66 0f f5 25 00 00 00 00 pmaddwd xmm4, XMMWORD PTR __xmm@11c8e09e11c8e09e11c8e09e11c8e09e 00516 66 41 0f 6f fc movdqa xmm7, xmm12 0051b 66 44 0f f5 25 00 00 00 00 pmaddwd xmm12, XMMWORD PTR __xmm@11c8f9c311c8f9c311c8f9c311c8f9c3 00524 66 0f 6f f3 movdqa xmm6, xmm3 00528 66 0f f5 1d 00 00 00 00 pmaddwd xmm3, XMMWORD PTR __xmm@11c8e09e11c8e09e11c8e09e11c8e09e 00530 66 0f f5 2d 00 00 00 00 pmaddwd xmm5, XMMWORD PTR __xmm@e09ee565e09ee565e09ee565e09ee565 00538 66 0f f5 35 00 00 00 00 pmaddwd xmm6, XMMWORD PTR __xmm@e09ee565e09ee565e09ee565e09ee565 00540 66 0f f5 3d 00 00 00 00 pmaddwd xmm7, XMMWORD PTR __xmm@f9c31a9df9c31a9df9c31a9df9c31a9d 00548 66 44 0f fe e2 paddd xmm12, xmm2 0054d 66 44 0f 7f 04 24 movdqa XMMWORD PTR y5o_h$1$[rsp], xmm8 00553 66 0f fe 24 24 paddd xmm4, XMMWORD PTR y5o_h$1$[rsp] 00558 66 0f fe d8 paddd xmm3, xmm0 0055c 66 0f fe ea paddd xmm5, xmm2 00560 66 44 0f 7f 64 24 40 movdqa XMMWORD PTR x7_h$1$[rsp], xmm12 00567 66 0f 6f 54 24 30 movdqa xmm2, XMMWORD PTR abiased_l$1$[rsp] 0056d 66 0f fe f1 paddd xmm6, xmm1 00571 66 0f fe 3c 24 paddd xmm7, XMMWORD PTR y5o_h$1$[rsp] 00576 66 45 0f 6f c3 movdqa xmm8, xmm11 0057b 66 44 0f f5 1d 00 00 00 00 pmaddwd xmm11, XMMWORD PTR __xmm@11c8f9c311c8f9c311c8f9c311c8f9c3 00584 66 44 0f 6f e2 movdqa xmm12, xmm2 00589 66 44 0f f5 05 00 00 00 00 pmaddwd xmm8, XMMWORD PTR __xmm@f9c31a9df9c31a9df9c31a9df9c31a9d 00592 66 41 0f fa d1 psubd xmm2, xmm9 00597 66 45 0f fe e1 paddd xmm12, xmm9 0059c 66 0f 7f 64 24 50 movdqa XMMWORD PTR x6_h$1$[rsp], xmm4 005a2 66 44 0f 6f 4c 24 10 movdqa xmm9, XMMWORD PTR abiased_h$1$[rsp] 005a9 66 41 0f 6f e6 movdqa xmm4, xmm14 005ae 66 45 0f fa ca psubd xmm9, xmm10 005b3 66 0f 7f 5c 24 60 movdqa XMMWORD PTR x6_l$1$[rsp], xmm3 005b9 66 0f 6f 5c 24 10 movdqa xmm3, XMMWORD PTR abiased_h$1$[rsp] 005bf 66 44 0f fe d9 paddd xmm11, xmm1 005c4 66 0f 6f 0d 00 00 00 00 movdqa xmm1, XMMWORD PTR __xmm@01010000010100000101000001010000 005cc 66 44 0f fe c0 paddd xmm8, xmm0 005d1 66 0f 6f 44 24 20 movdqa xmm0, XMMWORD PTR p2$1$[rsp] 005d7 66 44 0f fe c9 paddd xmm9, xmm1 005dc 66 0f fe d1 paddd xmm2, xmm1 005e0 66 44 0f 7f 4c 24 10 movdqa XMMWORD PTR abiased_h$1$[rsp], xmm9 005e7 66 44 0f fe e1 paddd xmm12, xmm1 005ec 66 44 0f 7f 5c 24 70 movdqa XMMWORD PTR x7_l$1$[rsp], xmm11 005f3 66 44 0f 6f d8 movdqa xmm11, xmm0 005f8 66 0f 7f 54 24 30 movdqa XMMWORD PTR abiased_l$1$[rsp], xmm2 005fe 66 41 0f fa c5 psubd xmm0, xmm13 00603 66 41 0f fe d0 paddd xmm2, xmm8 00608 66 0f fe c1 paddd xmm0, xmm1 0060c 66 0f 72 e2 11 psrad xmm2, 17 00611 66 0f 7f 44 24 20 movdqa XMMWORD PTR p2$1$[rsp], xmm0 00617 66 45 0f fe dd paddd xmm11, xmm13 0061c 66 44 0f fe d9 paddd xmm11, xmm1 00621 66 41 0f fe e7 paddd xmm4, xmm15 00626 66 0f fe e1 paddd xmm4, xmm1 0062a 66 45 0f 6f cb movdqa xmm9, xmm11 0062f 66 44 0f fe 4c 24 70 paddd xmm9, XMMWORD PTR x7_l$1$[rsp] 00636 66 0f 6f c4 movdqa xmm0, xmm4 0063a 66 0f fe 44 24 40 paddd xmm0, XMMWORD PTR x7_h$1$[rsp] 00640 66 41 0f fe da paddd xmm3, xmm10 00645 66 0f 72 e0 11 psrad xmm0, 17 0064a 66 0f fe d9 paddd xmm3, xmm1 0064e 66 41 0f 72 e1 11 psrad xmm9, 17 00654 66 45 0f fa f7 psubd xmm14, xmm15 00659 66 44 0f 6b c8 packssdw xmm9, xmm0 0065e 66 44 0f fe f1 paddd xmm14, xmm1 00663 66 0f 6f c3 movdqa xmm0, xmm3 00667 66 41 0f 6f cc movdqa xmm1, xmm12 0066c 66 0f fe 44 24 50 paddd xmm0, XMMWORD PTR x6_h$1$[rsp] 00672 66 0f fe 4c 24 60 paddd xmm1, XMMWORD PTR x6_l$1$[rsp] 00678 66 0f 72 e0 11 psrad xmm0, 17 0067d 66 0f 72 e1 11 psrad xmm1, 17 00682 66 0f 6b c8 packssdw xmm1, xmm0 00686 66 0f 6f 44 24 10 movdqa xmm0, XMMWORD PTR abiased_h$1$[rsp] 0068c 66 0f fe c7 paddd xmm0, xmm7 ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 00690 66 44 0f 67 c9 packuswb xmm9, xmm1 00695 66 0f 6f 4c 24 20 movdqa xmm1, XMMWORD PTR p2$1$[rsp] 0069b 66 0f 72 e0 11 psrad xmm0, 17 006a0 66 0f fe ce paddd xmm1, xmm6 006a4 66 0f 6b d0 packssdw xmm2, xmm0 006a8 66 41 0f 6f c6 movdqa xmm0, xmm14 006ad 66 0f fe c5 paddd xmm0, xmm5 006b1 66 0f 72 e1 11 psrad xmm1, 17 006b6 66 0f 72 e0 11 psrad xmm0, 17 006bb 66 0f 6b c8 packssdw xmm1, xmm0 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } 006bf 66 0f fa 64 24 40 psubd xmm4, XMMWORD PTR x7_h$1$[rsp] 006c5 4d 8d 1b lea r11, QWORD PTR [r11] 006c8 66 44 0f fa 64 24 60 psubd xmm12, XMMWORD PTR x6_l$1$[rsp] 006cf 66 44 0f fa f5 psubd xmm14, xmm5 006d4 66 0f fa 5c 24 50 psubd xmm3, XMMWORD PTR x6_h$1$[rsp] 006da 66 44 0f fa 5c 24 70 psubd xmm11, XMMWORD PTR x7_l$1$[rsp] 006e1 66 0f 6f 6c 24 10 movdqa xmm5, XMMWORD PTR abiased_h$1$[rsp] 006e7 66 0f 6f 44 24 30 movdqa xmm0, XMMWORD PTR abiased_l$1$[rsp] 006ed 66 0f fa ef psubd xmm5, xmm7 006f1 41 0f 28 7b d8 movaps xmm7, XMMWORD PTR [r11-40] 006f6 66 41 0f fa c0 psubd xmm0, xmm8 006fb 45 0f 28 43 c8 movaps xmm8, XMMWORD PTR [r11-56] 00700 45 0f 28 53 a8 movaps xmm10, XMMWORD PTR [r11-88] 00705 45 0f 28 ab 78 ff ff ff movaps xmm13, XMMWORD PTR [r11-136] 0070d 45 0f 28 bb 58 ff ff ff movaps xmm15, XMMWORD PTR [r11-168] 00715 66 0f 67 d1 packuswb xmm2, xmm1 00719 66 0f 6f 4c 24 20 movdqa xmm1, XMMWORD PTR p2$1$[rsp] 0071f 66 0f 72 e0 11 psrad xmm0, 17 00724 66 0f fa ce psubd xmm1, xmm6 00728 41 0f 28 73 e8 movaps xmm6, XMMWORD PTR [r11-24] 0072d 48 63 c2 movsxd rax, edx 00730 66 0f 72 e4 11 psrad xmm4, 17 00735 66 0f 72 e1 11 psrad xmm1, 17 0073a 66 0f 72 e3 11 psrad xmm3, 17 0073f 66 41 0f 72 e4 11 psrad xmm12, 17 00745 66 44 0f 6b e3 packssdw xmm12, xmm3 0074a 66 41 0f 72 e6 11 psrad xmm14, 17 00750 66 41 0f 6b ce packssdw xmm1, xmm14 00755 45 0f 28 b3 68 ff ff ff movaps xmm14, XMMWORD PTR [r11-152] 0075d 66 41 0f 72 e3 11 psrad xmm11, 17 00763 66 44 0f 6b dc packssdw xmm11, xmm4 00768 66 41 0f 6f e1 movdqa xmm4, xmm9 0076d 66 45 0f 67 e3 packuswb xmm12, xmm11 00772 45 0f 28 5b 98 movaps xmm11, XMMWORD PTR [r11-104] 00777 66 0f 72 e5 11 psrad xmm5, 17 0077c 66 0f 6b c5 packssdw xmm0, xmm5 00780 66 0f 67 c8 packuswb xmm1, xmm0 00784 66 0f 6f c2 movdqa xmm0, xmm2 00788 66 41 0f 60 c4 punpcklbw xmm0, xmm12 0078d 66 0f 60 e1 punpcklbw xmm4, xmm1 00791 66 44 0f 68 c9 punpckhbw xmm9, xmm1 00796 66 0f 6f dc movdqa xmm3, xmm4 0079a 66 0f 60 d8 punpcklbw xmm3, xmm0 0079e 66 0f 68 e0 punpckhbw xmm4, xmm0 007a2 66 0f 6f cb movdqa xmm1, xmm3 007a6 66 41 0f 68 d4 punpckhbw xmm2, xmm12 007ab 66 41 0f 6f c1 movdqa xmm0, xmm9 007b0 45 0f 28 63 88 movaps xmm12, XMMWORD PTR [r11-120] 007b5 66 0f 60 c2 punpcklbw xmm0, xmm2 007b9 66 0f 60 c8 punpcklbw xmm1, xmm0 007bd 66 0f d6 09 movq QWORD PTR [rcx], xmm1 007c1 48 03 c8 add rcx, rax 007c4 66 0f 68 d8 punpckhbw xmm3, xmm0 007c8 66 44 0f 68 ca punpckhbw xmm9, xmm2 007cd 66 0f 6f d4 movdqa xmm2, xmm4 007d1 66 41 0f 60 d1 punpcklbw xmm2, xmm9 007d6 66 41 0f 68 e1 punpckhbw xmm4, xmm9 007db 45 0f 28 4b b8 movaps xmm9, XMMWORD PTR [r11-72] 007e0 66 0f 70 c1 4e pshufd xmm0, xmm1, 78 ; 0000004eH 007e5 66 0f d6 01 movq QWORD PTR [rcx], xmm0 007e9 48 03 c8 add rcx, rax 007ec 66 0f 70 c3 4e pshufd xmm0, xmm3, 78 ; 0000004eH 007f1 66 0f d6 19 movq QWORD PTR [rcx], xmm3 007f5 48 03 c8 add rcx, rax 007f8 66 0f d6 01 movq QWORD PTR [rcx], xmm0 007fc 48 03 c8 add rcx, rax 007ff 66 0f 70 c2 4e pshufd xmm0, xmm2, 78 ; 0000004eH 00804 66 0f d6 11 movq QWORD PTR [rcx], xmm2 00808 48 03 c8 add rcx, rax 0080b 66 0f d6 01 movq QWORD PTR [rcx], xmm0 0080f 48 03 c8 add rcx, rax 00812 66 0f 70 c4 4e pshufd xmm0, xmm4, 78 ; 0000004eH 00817 66 0f d6 21 movq QWORD PTR [rcx], xmm4 0081b 66 0f d6 04 08 movq QWORD PTR [rax+rcx], xmm0 00820 49 8b e3 mov rsp, r11 00823 c3 ret 0 stbi__idct_simd ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get_marker _TEXT SEGMENT j$ = 48 stbi__get_marker PROC ; COMDAT ; 2393 : { 00000 40 57 push rdi 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } 00006 0f b6 81 28 48 00 00 movzx eax, BYTE PTR [rcx+18472] 0000d 48 8b f9 mov rdi, rcx 00010 3c ff cmp al, 255 ; 000000ffH 00012 74 0d je SHORT $LN4@stbi__get_ 00014 c6 81 28 48 00 00 ff mov BYTE PTR [rcx+18472], 255 ; 000000ffH ; 2401 : } 0001b 48 83 c4 20 add rsp, 32 ; 00000020H 0001f 5f pop rdi 00020 c3 ret 0 $LN4@stbi__get_: 00021 48 89 5c 24 30 mov QWORD PTR [rsp+48], rbx ; 2396 : x = stbi__get8(j->s); 00026 48 8b 19 mov rbx, QWORD PTR [rcx] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00029 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00030 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00037 72 15 jb SHORT $LN29@stbi__get_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00039 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0003d 74 79 je SHORT $LN18@stbi__get_ ; 1080 : stbi__refill_buffer(s); 0003f 48 8b cb mov rcx, rbx 00042 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00047 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN29@stbi__get_: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 0004e 0f b6 08 movzx ecx, BYTE PTR [rax] 00051 48 ff c0 inc rax 00054 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0005b 80 f9 ff cmp cl, 255 ; 000000ffH 0005e 75 58 jne SHORT $LN18@stbi__get_ $LL2@stbi__get_: ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes 00060 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00063 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0006a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00071 72 15 jb SHORT $LN30@stbi__get_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00073 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00077 74 2f je SHORT $LN13@stbi__get_ ; 1080 : stbi__refill_buffer(s); 00079 48 8b cb mov rcx, rbx 0007c e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00081 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN30@stbi__get_: ; 2398 : while (x == 0xff) 00088 0f b6 08 movzx ecx, BYTE PTR [rax] 0008b 48 ff c0 inc rax 0008e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00095 80 f9 ff cmp cl, 255 ; 000000ffH 00098 74 c6 je SHORT $LL2@stbi__get_ ; 2400 : return x; 0009a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0009f 0f b6 c1 movzx eax, cl ; 2401 : } 000a2 48 83 c4 20 add rsp, 32 ; 00000020H 000a6 5f pop rdi 000a7 c3 ret 0 $LN13@stbi__get_: 000a8 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 1083 : return 0; 000ad 32 c9 xor cl, cl ; 2400 : return x; 000af 0f b6 c1 movzx eax, cl ; 2401 : } 000b2 48 83 c4 20 add rsp, 32 ; 00000020H 000b6 5f pop rdi 000b7 c3 ret 0 $LN18@stbi__get_: 000b8 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 2397 : if (x != 0xff) return STBI__MARKER_none; 000bd b0 ff mov al, 255 ; 000000ffH ; 2401 : } 000bf 48 83 c4 20 add rsp, 32 ; 00000020H 000c3 5f pop rdi 000c4 c3 ret 0 stbi__get_marker ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_reset _TEXT SEGMENT j$ = 8 stbi__jpeg_reset PROC ; COMDAT ; 2411 : j->code_bits = 0; 00000 45 33 c0 xor r8d, r8d ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; 00003 c6 81 28 48 00 00 ff mov BYTE PTR [rcx+18472], 255 ; 000000ffH 0000a 44 89 81 d8 47 00 00 mov DWORD PTR [rcx+18392], r8d ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 00011 ba ff ff ff 7f mov edx, 2147483647 ; 7fffffffH 00016 44 89 81 78 47 00 00 mov DWORD PTR [rcx+18296], r8d 0001d 44 89 81 18 47 00 00 mov DWORD PTR [rcx+18200], r8d 00024 44 89 81 b8 46 00 00 mov DWORD PTR [rcx+18104], r8d 0002b 8b 81 68 48 00 00 mov eax, DWORD PTR [rcx+18536] 00031 85 c0 test eax, eax 00033 4c 89 81 20 48 00 00 mov QWORD PTR [rcx+18464], r8 0003a 0f 45 d0 cmovne edx, eax 0003d 44 89 81 2c 48 00 00 mov DWORD PTR [rcx+18476], r8d 00044 89 91 6c 48 00 00 mov DWORD PTR [rcx+18540], edx ; 2417 : j->eob_run = 0; 0004a 44 89 81 44 48 00 00 mov DWORD PTR [rcx+18500], r8d ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } 00051 c3 ret 0 stbi__jpeg_reset ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_entropy_coded_data _TEXT SEGMENT k$1$ = 64 j$1$ = 68 tv1823 = 72 tv1822 = 72 data$1 = 80 data$2 = 80 __$ArrayPad$ = 208 z$ = 272 stbi__parse_entropy_coded_data PROC ; COMDAT ; 2423 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 0000a 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi 0000f 57 push rdi 00010 41 54 push r12 00012 41 55 push r13 00014 41 56 push r14 00016 41 57 push r15 00018 48 81 ec e0 00 00 00 sub rsp, 224 ; 000000e0H 0001f 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00026 48 33 c4 xor rax, rsp 00029 48 89 84 24 d0 00 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 00031 c7 81 d8 47 00 00 00 00 00 00 mov DWORD PTR [rcx+18392], 0 ; 2423 : { 0003b 48 8b d9 mov rbx, rcx ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 0003e c7 81 78 47 00 00 00 00 00 00 mov DWORD PTR [rcx+18296], 0 00048 c7 81 18 47 00 00 00 00 00 00 mov DWORD PTR [rcx+18200], 0 00052 c7 81 b8 46 00 00 00 00 00 00 mov DWORD PTR [rcx+18104], 0 ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 0005c 8b 81 68 48 00 00 mov eax, DWORD PTR [rcx+18536] 00062 85 c0 test eax, eax 00064 48 c7 81 20 48 00 00 00 00 00 00 mov QWORD PTR [rcx+18464], 0 0006f c7 81 2c 48 00 00 00 00 00 00 mov DWORD PTR [rcx+18476], 0 00079 c6 81 28 48 00 00 ff mov BYTE PTR [rcx+18472], 255 ; 000000ffH 00080 b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 00085 0f 45 c8 cmovne ecx, eax ; 2417 : j->eob_run = 0; 00088 c7 83 44 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18500], 0 ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { 00092 83 bb 30 48 00 00 00 cmp DWORD PTR [rbx+18480], 0 00099 8b 83 54 48 00 00 mov eax, DWORD PTR [rbx+18516] ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 0009f 89 8b 6c 48 00 00 mov DWORD PTR [rbx+18540], ecx ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { 000a5 0f 85 13 04 00 00 jne $LN44@stbi__pars ; 2426 : if (z->scan_n == 1) { 000ab 83 f8 01 cmp eax, 1 000ae 0f 85 d2 01 00 00 jne $LN46@stbi__pars ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; 000b4 4c 63 a3 58 48 00 00 movsxd r12, DWORD PTR [rbx+18520] ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { 000bb 45 33 f6 xor r14d, r14d 000be 4b 8d 34 64 lea rsi, QWORD PTR [r12+r12*2] 000c2 48 c1 e6 05 shl rsi, 5 000c6 48 03 f3 add rsi, rbx 000c9 44 8b be bc 46 00 00 mov r15d, DWORD PTR [rsi+18108] 000d0 44 8b ae c0 46 00 00 mov r13d, DWORD PTR [rsi+18112] 000d7 41 83 c7 07 add r15d, 7 000db 41 83 c5 07 add r13d, 7 000df 41 c1 ff 03 sar r15d, 3 000e3 41 c1 fd 03 sar r13d, 3 000e7 45 85 ed test r13d, r13d 000ea 0f 8e 60 01 00 00 jle $LN271@stbi__pars $LL4@stbi__pars: ; 2437 : for (i = 0; i < w; ++i) { 000f0 33 ff xor edi, edi 000f2 45 85 ff test r15d, r15d 000f5 0f 8e 49 01 00 00 jle $LN2@stbi__pars 000fb 33 ed xor ebp, ebp 000fd 0f 1f 00 npad 3 $LL7@stbi__pars: ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; 00100 48 63 8e b4 46 00 00 movsxd rcx, DWORD PTR [rsi+18100] 00107 48 63 86 b0 46 00 00 movsxd rax, DWORD PTR [rsi+18096] 0010e 48 8b d1 mov rdx, rcx 00111 4c 63 96 ac 46 00 00 movsxd r10, DWORD PTR [rsi+18092] 00118 48 c1 e2 0a shl rdx, 10 0011c 4c 69 c9 90 06 00 00 imul r9, rcx, 1680 ; 00000690H 00123 4c 69 c0 90 06 00 00 imul r8, rax, 1680 ; 00000690H 0012a 49 c1 e2 07 shl r10, 7 0012e 48 81 c2 88 36 00 00 add rdx, 13960 ; 00003688H 00135 48 03 d3 add rdx, rbx 00138 49 81 c2 88 34 00 00 add r10, 13448 ; 00003488H 0013f 4c 03 d3 add r10, rbx 00142 49 81 c1 48 1a 00 00 add r9, 6728 ; 00001a48H 00149 4c 89 54 24 30 mov QWORD PTR [rsp+48], r10 0014e 4c 03 cb add r9, rbx 00151 44 89 64 24 28 mov DWORD PTR [rsp+40], r12d 00156 48 8b cb mov rcx, rbx 00159 49 83 c0 08 add r8, 8 0015d 48 89 54 24 20 mov QWORD PTR [rsp+32], rdx 00162 4c 03 c3 add r8, rbx 00165 48 8d 54 24 50 lea rdx, QWORD PTR data$2[rsp] 0016a e8 00 00 00 00 call stbi__jpeg_decode_block 0016f 85 c0 test eax, eax 00171 0f 84 8f 06 00 00 je $LN224@stbi__pars ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); 00177 8b 96 c4 46 00 00 mov edx, DWORD PTR [rsi+18116] 0017d 4c 8d 44 24 50 lea r8, QWORD PTR data$2[rsp] 00182 8b c2 mov eax, edx 00184 41 0f af c6 imul eax, r14d 00188 c1 e0 03 shl eax, 3 0018b 48 63 c8 movsxd rcx, eax 0018e 48 03 8e d0 46 00 00 add rcx, QWORD PTR [rsi+18128] 00195 48 63 c5 movsxd rax, ebp 00198 48 03 c8 add rcx, rax 0019b ff 93 70 48 00 00 call QWORD PTR [rbx+18544] ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { 001a1 ff 8b 6c 48 00 00 dec DWORD PTR [rbx+18540] 001a7 83 bb 6c 48 00 00 00 cmp DWORD PTR [rbx+18540], 0 001ae 0f 8f 82 00 00 00 jg $LN5@stbi__pars ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); 001b4 83 bb 24 48 00 00 18 cmp DWORD PTR [rbx+18468], 24 001bb 7d 08 jge SHORT $LN50@stbi__pars 001bd 48 8b cb mov rcx, rbx 001c0 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN50@stbi__pars: ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; 001c5 0f b6 83 28 48 00 00 movzx eax, BYTE PTR [rbx+18472] 001cc 04 30 add al, 48 ; 00000030H 001ce 3c 07 cmp al, 7 001d0 77 7e ja SHORT $LN271@stbi__pars ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 001d2 c7 83 d8 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18392], 0 ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 001dc b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 001e1 c7 83 78 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18296], 0 001eb c7 83 18 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18200], 0 001f5 c7 83 b8 46 00 00 00 00 00 00 mov DWORD PTR [rbx+18104], 0 001ff 8b 83 68 48 00 00 mov eax, DWORD PTR [rbx+18536] 00205 85 c0 test eax, eax 00207 48 c7 83 20 48 00 00 00 00 00 00 mov QWORD PTR [rbx+18464], 0 00212 0f 45 c8 cmovne ecx, eax 00215 c7 83 2c 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18476], 0 0021f 89 8b 6c 48 00 00 mov DWORD PTR [rbx+18540], ecx 00225 c6 83 28 48 00 00 ff mov BYTE PTR [rbx+18472], 255 ; 000000ffH ; 2417 : j->eob_run = 0; 0022c c7 83 44 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18500], 0 $LN5@stbi__pars: ; 2437 : for (i = 0; i < w; ++i) { 00236 ff c7 inc edi 00238 83 c5 08 add ebp, 8 0023b 41 3b ff cmp edi, r15d 0023e 0f 8c bc fe ff ff jl $LL7@stbi__pars $LN2@stbi__pars: ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { 00244 41 ff c6 inc r14d 00247 45 3b f5 cmp r14d, r13d 0024a 0f 8c a0 fe ff ff jl $LL4@stbi__pars $LN271@stbi__pars: ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; 00250 b8 01 00 00 00 mov eax, 1 $LN59@stbi__pars: ; 2546 : } ; 2547 : } ; 2548 : } 00255 48 8b 8c 24 d0 00 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0025d 48 33 cc xor rcx, rsp 00260 e8 00 00 00 00 call __security_check_cookie 00265 4c 8d 9c 24 e0 00 00 00 lea r11, QWORD PTR [rsp+224] 0026d 49 8b 5b 38 mov rbx, QWORD PTR [r11+56] 00271 49 8b 6b 40 mov rbp, QWORD PTR [r11+64] 00275 49 8b 73 48 mov rsi, QWORD PTR [r11+72] 00279 49 8b e3 mov rsp, r11 0027c 41 5f pop r15 0027e 41 5e pop r14 00280 41 5d pop r13 00282 41 5c pop r12 00284 5f pop rdi 00285 c3 ret 0 $LN46@stbi__pars: ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { 00286 33 ed xor ebp, ebp 00288 89 6c 24 44 mov DWORD PTR j$1$[rsp], ebp 0028c 39 ab 94 46 00 00 cmp DWORD PTR [rbx+18068], ebp 00292 7e bc jle SHORT $LN271@stbi__pars 00294 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL10@stbi__pars: ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { 002a0 45 33 ed xor r13d, r13d 002a3 44 39 ab 90 46 00 00 cmp DWORD PTR [rbx+18064], r13d 002aa 0f 8e f7 01 00 00 jle $LN8@stbi__pars $LL13@stbi__pars: ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { 002b0 33 d2 xor edx, edx 002b2 89 54 24 40 mov DWORD PTR k$1$[rsp], edx 002b6 39 93 54 48 00 00 cmp DWORD PTR [rbx+18516], edx 002bc 0f 8e 3c 01 00 00 jle $LN15@stbi__pars 002c2 48 8d 83 58 48 00 00 lea rax, QWORD PTR [rbx+18520] 002c9 48 89 44 24 48 mov QWORD PTR tv1823[rsp], rax 002ce 66 90 npad 2 $LL16@stbi__pars: ; 2460 : int n = z->order[k]; 002d0 4c 63 20 movsxd r12, DWORD PTR [rax] ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { 002d3 45 33 ff xor r15d, r15d 002d6 4b 8d 34 64 lea rsi, QWORD PTR [r12+r12*2] 002da 48 c1 e6 05 shl rsi, 5 002de 48 03 f3 add rsi, rbx 002e1 44 39 be a8 46 00 00 cmp DWORD PTR [rsi+18088], r15d 002e8 0f 8e f0 00 00 00 jle $LN14@stbi__pars 002ee 66 90 npad 2 $LL19@stbi__pars: ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { 002f0 8b be a4 46 00 00 mov edi, DWORD PTR [rsi+18084] 002f6 45 33 f6 xor r14d, r14d 002f9 85 ff test edi, edi 002fb 0f 8e c9 00 00 00 jle $LN17@stbi__pars $LL22@stbi__pars: ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; 00301 48 63 8e b4 46 00 00 movsxd rcx, DWORD PTR [rsi+18100] 00308 48 63 86 b0 46 00 00 movsxd rax, DWORD PTR [rsi+18096] 0030f 48 8b d1 mov rdx, rcx 00312 4c 63 96 ac 46 00 00 movsxd r10, DWORD PTR [rsi+18092] 00319 0f af ae a8 46 00 00 imul ebp, DWORD PTR [rsi+18088] 00320 48 c1 e2 0a shl rdx, 10 00324 4c 69 c9 90 06 00 00 imul r9, rcx, 1680 ; 00000690H 0032b 4c 69 c0 90 06 00 00 imul r8, rax, 1680 ; 00000690H 00332 49 c1 e2 07 shl r10, 7 00336 48 81 c2 88 36 00 00 add rdx, 13960 ; 00003688H 0033d 48 03 d3 add rdx, rbx 00340 49 81 c2 88 34 00 00 add r10, 13448 ; 00003488H 00347 4c 03 d3 add r10, rbx 0034a 49 81 c1 48 1a 00 00 add r9, 6728 ; 00001a48H 00351 4c 89 54 24 30 mov QWORD PTR [rsp+48], r10 00356 4c 03 cb add r9, rbx 00359 44 89 64 24 28 mov DWORD PTR [rsp+40], r12d 0035e 48 8b cb mov rcx, rbx 00361 49 83 c0 08 add r8, 8 00365 48 89 54 24 20 mov QWORD PTR [rsp+32], rdx 0036a 4c 03 c3 add r8, rbx 0036d 48 8d 54 24 50 lea rdx, QWORD PTR data$1[rsp] 00372 41 03 ef add ebp, r15d 00375 e8 00 00 00 00 call stbi__jpeg_decode_block 0037a 85 c0 test eax, eax 0037c 0f 84 84 04 00 00 je $LN224@stbi__pars ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); 00382 8b 96 c4 46 00 00 mov edx, DWORD PTR [rsi+18116] 00388 4c 8d 44 24 50 lea r8, QWORD PTR data$1[rsp] 0038d 8b c2 mov eax, edx 0038f 41 0f af fd imul edi, r13d 00393 0f af c5 imul eax, ebp 00396 41 03 fe add edi, r14d 00399 c1 e0 03 shl eax, 3 0039c 48 98 cdqe 0039e c1 e7 03 shl edi, 3 003a1 48 63 cf movsxd rcx, edi 003a4 48 03 c8 add rcx, rax 003a7 48 03 8e d0 46 00 00 add rcx, QWORD PTR [rsi+18128] 003ae ff 93 70 48 00 00 call QWORD PTR [rbx+18544] 003b4 8b be a4 46 00 00 mov edi, DWORD PTR [rsi+18084] 003ba 41 ff c6 inc r14d 003bd 8b 6c 24 44 mov ebp, DWORD PTR j$1$[rsp] 003c1 44 3b f7 cmp r14d, edi 003c4 0f 8c 37 ff ff ff jl $LL22@stbi__pars $LN17@stbi__pars: ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { 003ca 41 ff c7 inc r15d 003cd 44 3b be a8 46 00 00 cmp r15d, DWORD PTR [rsi+18088] 003d4 0f 8c 16 ff ff ff jl $LL19@stbi__pars 003da 8b 54 24 40 mov edx, DWORD PTR k$1$[rsp] $LN14@stbi__pars: ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { 003de 48 8b 44 24 48 mov rax, QWORD PTR tv1823[rsp] 003e3 ff c2 inc edx 003e5 48 83 c0 04 add rax, 4 003e9 89 54 24 40 mov DWORD PTR k$1$[rsp], edx 003ed 48 89 44 24 48 mov QWORD PTR tv1823[rsp], rax 003f2 3b 93 54 48 00 00 cmp edx, DWORD PTR [rbx+18516] 003f8 0f 8c d2 fe ff ff jl $LL16@stbi__pars $LN15@stbi__pars: ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { 003fe ff 8b 6c 48 00 00 dec DWORD PTR [rbx+18540] 00404 83 bb 6c 48 00 00 00 cmp DWORD PTR [rbx+18540], 0 0040b 0f 8f 86 00 00 00 jg $LN11@stbi__pars ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); 00411 83 bb 24 48 00 00 18 cmp DWORD PTR [rbx+18468], 24 00418 7d 08 jge SHORT $LN55@stbi__pars 0041a 48 8b cb mov rcx, rbx 0041d e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN55@stbi__pars: ; 2477 : if (!STBI__RESTART(z->marker)) return 1; 00422 0f b6 83 28 48 00 00 movzx eax, BYTE PTR [rbx+18472] 00429 04 30 add al, 48 ; 00000030H 0042b 3c 07 cmp al, 7 0042d 0f 87 1d fe ff ff ja $LN271@stbi__pars ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 00433 c7 83 d8 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18392], 0 ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 0043d b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 00442 c7 83 78 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18296], 0 0044c c7 83 18 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18200], 0 00456 c7 83 b8 46 00 00 00 00 00 00 mov DWORD PTR [rbx+18104], 0 00460 8b 83 68 48 00 00 mov eax, DWORD PTR [rbx+18536] 00466 85 c0 test eax, eax 00468 48 c7 83 20 48 00 00 00 00 00 00 mov QWORD PTR [rbx+18464], 0 00473 0f 45 c8 cmovne ecx, eax 00476 c7 83 2c 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18476], 0 00480 89 8b 6c 48 00 00 mov DWORD PTR [rbx+18540], ecx 00486 c6 83 28 48 00 00 ff mov BYTE PTR [rbx+18472], 255 ; 000000ffH ; 2417 : j->eob_run = 0; 0048d c7 83 44 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18500], 0 $LN11@stbi__pars: ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { 00497 41 ff c5 inc r13d 0049a 44 3b ab 90 46 00 00 cmp r13d, DWORD PTR [rbx+18064] 004a1 0f 8c 09 fe ff ff jl $LL13@stbi__pars $LN8@stbi__pars: ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { 004a7 ff c5 inc ebp 004a9 89 6c 24 44 mov DWORD PTR j$1$[rsp], ebp 004ad 3b ab 94 46 00 00 cmp ebp, DWORD PTR [rbx+18068] 004b3 0f 8c e7 fd ff ff jl $LL10@stbi__pars ; 2540 : if (!STBI__RESTART(z->marker)) return 1; 004b9 e9 92 fd ff ff jmp $LN271@stbi__pars $LN44@stbi__pars: ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { 004be 83 f8 01 cmp eax, 1 004c1 0f 85 81 01 00 00 jne $LN58@stbi__pars ; 2487 : int i, j; ; 2488 : int n = z->order[0]; 004c7 4c 63 b3 58 48 00 00 movsxd r14, DWORD PTR [rbx+18520] ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { 004ce 33 f6 xor esi, esi 004d0 4f 8d 24 76 lea r12, QWORD PTR [r14+r14*2] 004d4 49 c1 e4 05 shl r12, 5 004d8 41 8b ac 1c bc 46 00 00 mov ebp, DWORD PTR [r12+rbx+18108] 004e0 45 8b bc 1c c0 46 00 00 mov r15d, DWORD PTR [r12+rbx+18112] 004e8 83 c5 07 add ebp, 7 004eb 41 83 c7 07 add r15d, 7 004ef c1 fd 03 sar ebp, 3 004f2 41 c1 ff 03 sar r15d, 3 004f6 45 85 ff test r15d, r15d 004f9 0f 8e 51 fd ff ff jle $LN271@stbi__pars 004ff 90 npad 1 $LL25@stbi__pars: ; 2496 : for (i = 0; i < w; ++i) { 00500 33 ff xor edi, edi 00502 85 ed test ebp, ebp 00504 0f 8e 2e 01 00 00 jle $LN23@stbi__pars 0050a 66 0f 1f 44 00 00 npad 6 $LL28@stbi__pars: ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); 00510 8b c6 mov eax, esi 00512 41 0f af 84 1c f8 46 00 00 imul eax, DWORD PTR [r12+rbx+18168] 0051b 03 c7 add eax, edi 0051d c1 e0 06 shl eax, 6 ; 2498 : if (z->spec_start == 0) { 00520 83 bb 34 48 00 00 00 cmp DWORD PTR [rbx+18484], 0 00527 48 63 c8 movsxd rcx, eax 0052a 49 8b 84 1c f0 46 00 00 mov rax, QWORD PTR [r12+rbx+18160] 00532 48 8d 14 48 lea rdx, QWORD PTR [rax+rcx*2] 00536 75 23 jne SHORT $LN60@stbi__pars ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) 00538 4a 63 84 23 b0 46 00 00 movsxd rax, DWORD PTR [rbx+r12+18096] 00540 45 8b ce mov r9d, r14d 00543 4c 69 c0 90 06 00 00 imul r8, rax, 1680 ; 00000690H 0054a 48 8b cb mov rcx, rbx 0054d 49 83 c0 08 add r8, 8 00551 4c 03 c3 add r8, rbx 00554 e8 00 00 00 00 call stbi__jpeg_decode_block_prog_dc ; 2500 : return 0; ; 2501 : } 00559 eb 32 jmp SHORT $LN310@stbi__pars $LN60@stbi__pars: ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) 0055b 4a 63 8c 23 b4 46 00 00 movsxd rcx, DWORD PTR [rbx+r12+18100] 00563 4c 69 c1 90 06 00 00 imul r8, rcx, 1680 ; 00000690H 0056a 4c 8b c9 mov r9, rcx 0056d 48 8b cb mov rcx, rbx 00570 49 c1 e1 0a shl r9, 10 00574 49 81 c0 48 1a 00 00 add r8, 6728 ; 00001a48H 0057b 49 81 c1 88 36 00 00 add r9, 13960 ; 00003688H 00582 4c 03 c3 add r8, rbx 00585 4c 03 cb add r9, rbx 00588 e8 00 00 00 00 call stbi__jpeg_decode_block_prog_ac $LN310@stbi__pars: ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { 0058d 85 c0 test eax, eax 0058f 0f 84 71 02 00 00 je $LN224@stbi__pars 00595 ff 8b 6c 48 00 00 dec DWORD PTR [rbx+18540] 0059b 83 bb 6c 48 00 00 00 cmp DWORD PTR [rbx+18540], 0 005a2 0f 8f 86 00 00 00 jg $LN26@stbi__pars ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); 005a8 83 bb 24 48 00 00 18 cmp DWORD PTR [rbx+18468], 24 005af 7d 08 jge SHORT $LN65@stbi__pars 005b1 48 8b cb mov rcx, rbx 005b4 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN65@stbi__pars: ; 2510 : if (!STBI__RESTART(z->marker)) return 1; 005b9 0f b6 83 28 48 00 00 movzx eax, BYTE PTR [rbx+18472] 005c0 04 30 add al, 48 ; 00000030H 005c2 3c 07 cmp al, 7 005c4 0f 87 86 fc ff ff ja $LN271@stbi__pars ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 005ca c7 83 d8 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18392], 0 ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 005d4 b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 005d9 c7 83 78 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18296], 0 005e3 c7 83 18 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18200], 0 005ed c7 83 b8 46 00 00 00 00 00 00 mov DWORD PTR [rbx+18104], 0 005f7 8b 83 68 48 00 00 mov eax, DWORD PTR [rbx+18536] 005fd 85 c0 test eax, eax 005ff 48 c7 83 20 48 00 00 00 00 00 00 mov QWORD PTR [rbx+18464], 0 0060a 0f 45 c8 cmovne ecx, eax 0060d c7 83 2c 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18476], 0 00617 89 8b 6c 48 00 00 mov DWORD PTR [rbx+18540], ecx 0061d c6 83 28 48 00 00 ff mov BYTE PTR [rbx+18472], 255 ; 000000ffH ; 2417 : j->eob_run = 0; 00624 c7 83 44 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18500], 0 $LN26@stbi__pars: ; 2496 : for (i = 0; i < w; ++i) { 0062e ff c7 inc edi 00630 3b fd cmp edi, ebp 00632 0f 8c d8 fe ff ff jl $LL28@stbi__pars $LN23@stbi__pars: ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { 00638 ff c6 inc esi 0063a 41 3b f7 cmp esi, r15d 0063d 0f 8c bd fe ff ff jl $LL25@stbi__pars ; 2540 : if (!STBI__RESTART(z->marker)) return 1; 00643 e9 08 fc ff ff jmp $LN271@stbi__pars $LN58@stbi__pars: ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { 00648 45 33 e4 xor r12d, r12d 0064b 44 39 a3 94 46 00 00 cmp DWORD PTR [rbx+18068], r12d 00652 0f 8e f8 fb ff ff jle $LN271@stbi__pars 00658 0f 1f 84 00 00 00 00 00 npad 8 $LL31@stbi__pars: ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { 00660 45 33 ff xor r15d, r15d 00663 44 39 bb 90 46 00 00 cmp DWORD PTR [rbx+18064], r15d 0066a 0f 8e 81 01 00 00 jle $LN29@stbi__pars $LL34@stbi__pars: ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { 00670 45 33 ed xor r13d, r13d 00673 44 39 ab 54 48 00 00 cmp DWORD PTR [rbx+18516], r13d 0067a 0f 8e c8 00 00 00 jle $LN269@stbi__pars 00680 48 8d 83 58 48 00 00 lea rax, QWORD PTR [rbx+18520] 00687 48 89 44 24 48 mov QWORD PTR tv1822[rsp], rax 0068c 0f 1f 40 00 npad 4 $LL37@stbi__pars: ; 2523 : int n = z->order[k]; 00690 4c 63 30 movsxd r14, DWORD PTR [rax] ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { 00693 33 ed xor ebp, ebp 00695 4b 8d 34 76 lea rsi, QWORD PTR [r14+r14*2] 00699 48 c1 e6 05 shl rsi, 5 0069d 48 03 f3 add rsi, rbx 006a0 39 ae a8 46 00 00 cmp DWORD PTR [rsi+18088], ebp 006a6 0f 8e 7e 00 00 00 jle $LN35@stbi__pars 006ac 0f 1f 40 00 npad 4 $LL40@stbi__pars: ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { 006b0 8b 86 a4 46 00 00 mov eax, DWORD PTR [rsi+18084] 006b6 33 ff xor edi, edi 006b8 85 c0 test eax, eax 006ba 7e 64 jle SHORT $LN38@stbi__pars 006bc 0f 1f 40 00 npad 4 $LL43@stbi__pars: ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); 006c0 41 0f af c7 imul eax, r15d 006c4 41 8b cc mov ecx, r12d 006c7 0f af 8e a8 46 00 00 imul ecx, DWORD PTR [rsi+18088] ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) 006ce 45 8b ce mov r9d, r14d 006d1 03 cd add ecx, ebp 006d3 0f af 8e f8 46 00 00 imul ecx, DWORD PTR [rsi+18168] 006da 03 cf add ecx, edi 006dc 03 c1 add eax, ecx 006de c1 e0 06 shl eax, 6 006e1 48 63 c8 movsxd rcx, eax 006e4 48 8b 86 f0 46 00 00 mov rax, QWORD PTR [rsi+18160] 006eb 48 8d 14 48 lea rdx, QWORD PTR [rax+rcx*2] 006ef 48 63 86 b0 46 00 00 movsxd rax, DWORD PTR [rsi+18096] 006f6 4c 69 c0 90 06 00 00 imul r8, rax, 1680 ; 00000690H 006fd 48 8b cb mov rcx, rbx 00700 49 83 c0 08 add r8, 8 00704 4c 03 c3 add r8, rbx 00707 e8 00 00 00 00 call stbi__jpeg_decode_block_prog_dc 0070c 85 c0 test eax, eax 0070e 0f 84 f2 00 00 00 je $LN224@stbi__pars ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { 00714 8b 86 a4 46 00 00 mov eax, DWORD PTR [rsi+18084] 0071a ff c7 inc edi 0071c 3b f8 cmp edi, eax 0071e 7c a0 jl SHORT $LL43@stbi__pars $LN38@stbi__pars: ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { 00720 ff c5 inc ebp 00722 3b ae a8 46 00 00 cmp ebp, DWORD PTR [rsi+18088] 00728 7c 86 jl SHORT $LL40@stbi__pars $LN35@stbi__pars: ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { 0072a 48 8b 44 24 48 mov rax, QWORD PTR tv1822[rsp] 0072f 41 ff c5 inc r13d 00732 48 83 c0 04 add rax, 4 00736 48 89 44 24 48 mov QWORD PTR tv1822[rsp], rax 0073b 44 3b ab 54 48 00 00 cmp r13d, DWORD PTR [rbx+18516] 00742 0f 8c 48 ff ff ff jl $LL37@stbi__pars $LN269@stbi__pars: ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { 00748 ff 8b 6c 48 00 00 dec DWORD PTR [rbx+18540] 0074e 83 bb 6c 48 00 00 00 cmp DWORD PTR [rbx+18540], 0 00755 0f 8f 86 00 00 00 jg $LN32@stbi__pars ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); 0075b 83 bb 24 48 00 00 18 cmp DWORD PTR [rbx+18468], 24 00762 7d 08 jge SHORT $LN70@stbi__pars 00764 48 8b cb mov rcx, rbx 00767 e8 00 00 00 00 call stbi__grow_buffer_unsafe $LN70@stbi__pars: ; 2540 : if (!STBI__RESTART(z->marker)) return 1; 0076c 0f b6 83 28 48 00 00 movzx eax, BYTE PTR [rbx+18472] 00773 04 30 add al, 48 ; 00000030H 00775 3c 07 cmp al, 7 00777 0f 87 d3 fa ff ff ja $LN271@stbi__pars ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; 0077d c7 83 d8 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18392], 0 ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; 00787 b9 ff ff ff 7f mov ecx, 2147483647 ; 7fffffffH 0078c c7 83 78 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18296], 0 00796 c7 83 18 47 00 00 00 00 00 00 mov DWORD PTR [rbx+18200], 0 007a0 c7 83 b8 46 00 00 00 00 00 00 mov DWORD PTR [rbx+18104], 0 007aa 8b 83 68 48 00 00 mov eax, DWORD PTR [rbx+18536] 007b0 85 c0 test eax, eax 007b2 48 c7 83 20 48 00 00 00 00 00 00 mov QWORD PTR [rbx+18464], 0 007bd 0f 45 c8 cmovne ecx, eax 007c0 c7 83 2c 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18476], 0 007ca 89 8b 6c 48 00 00 mov DWORD PTR [rbx+18540], ecx 007d0 c6 83 28 48 00 00 ff mov BYTE PTR [rbx+18472], 255 ; 000000ffH ; 2417 : j->eob_run = 0; 007d7 c7 83 44 48 00 00 00 00 00 00 mov DWORD PTR [rbx+18500], 0 $LN32@stbi__pars: ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { 007e1 41 ff c7 inc r15d 007e4 44 3b bb 90 46 00 00 cmp r15d, DWORD PTR [rbx+18064] 007eb 0f 8c 7f fe ff ff jl $LL34@stbi__pars $LN29@stbi__pars: ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { 007f1 41 ff c4 inc r12d 007f4 44 3b a3 94 46 00 00 cmp r12d, DWORD PTR [rbx+18068] 007fb 0f 8c 5f fe ff ff jl $LL31@stbi__pars 00801 e9 4a fa ff ff jmp $LN271@stbi__pars $LN224@stbi__pars: ; 2532 : return 0; 00806 33 c0 xor eax, eax 00808 e9 48 fa ff ff jmp $LN59@stbi__pars stbi__parse_entropy_coded_data ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_dequantize _TEXT SEGMENT data$ = 8 dequant$ = 16 stbi__jpeg_dequantize PROC ; COMDAT ; 2551 : { 00000 4c 8b c2 mov r8, rdx ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) 00003 48 8d 51 7e lea rdx, QWORD PTR [rcx+126] 00007 49 8d 40 7e lea rax, QWORD PTR [r8+126] 0000b 48 3b c8 cmp rcx, rax 0000e 77 2a ja SHORT $LN10@stbi__jpeg 00010 49 3b d0 cmp rdx, r8 00013 72 25 jb SHORT $LN10@stbi__jpeg 00015 4c 2b c1 sub r8, rcx 00018 41 b9 40 00 00 00 mov r9d, 64 ; 00000040H 0001e 66 90 npad 2 $LL8@stbi__jpeg: ; 2554 : data[i] *= dequant[i]; 00020 41 0f bf 04 08 movsx eax, WORD PTR [r8+rcx] 00025 0f bf 11 movsx edx, WORD PTR [rcx] 00028 48 8d 49 02 lea rcx, QWORD PTR [rcx+2] 0002c 0f af d0 imul edx, eax 0002f 66 89 51 fe mov WORD PTR [rcx-2], dx 00033 49 83 e9 01 sub r9, 1 00037 75 e7 jne SHORT $LL8@stbi__jpeg ; 2555 : } 00039 c3 ret 0 $LN10@stbi__jpeg: ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) 0003a 48 8d 41 10 lea rax, QWORD PTR [rcx+16] 0003e 4c 2b c1 sub r8, rcx 00041 b9 02 00 00 00 mov ecx, 2 00046 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL4@stbi__jpeg: ; 2554 : data[i] *= dequant[i]; 00050 f3 0f 6f 40 f0 movdqu xmm0, XMMWORD PTR [rax-16] 00055 f3 42 0f 6f 4c 00 f0 movdqu xmm1, XMMWORD PTR [rax+r8-16] 0005c f3 42 0f 6f 14 00 movdqu xmm2, XMMWORD PTR [rax+r8] 00062 48 8d 40 40 lea rax, QWORD PTR [rax+64] 00066 66 0f d5 c8 pmullw xmm1, xmm0 0006a f3 0f 7f 48 b0 movdqu XMMWORD PTR [rax-80], xmm1 0006f f3 0f 6f 40 c0 movdqu xmm0, XMMWORD PTR [rax-64] 00074 f3 42 0f 6f 4c 00 d0 movdqu xmm1, XMMWORD PTR [rax+r8-48] 0007b 66 0f d5 d0 pmullw xmm2, xmm0 0007f f3 0f 7f 50 c0 movdqu XMMWORD PTR [rax-64], xmm2 00084 f3 0f 6f 40 d0 movdqu xmm0, XMMWORD PTR [rax-48] 00089 66 0f d5 c8 pmullw xmm1, xmm0 0008d f3 0f 7f 48 d0 movdqu XMMWORD PTR [rax-48], xmm1 00092 f3 0f 6f 40 e0 movdqu xmm0, XMMWORD PTR [rax-32] 00097 f3 42 0f 6f 4c 00 e0 movdqu xmm1, XMMWORD PTR [rax+r8-32] 0009e 66 0f d5 c8 pmullw xmm1, xmm0 000a2 f3 0f 7f 48 e0 movdqu XMMWORD PTR [rax-32], xmm1 000a7 48 83 e9 01 sub rcx, 1 000ab 75 a3 jne SHORT $LL4@stbi__jpeg ; 2555 : } 000ad c3 ret 0 stbi__jpeg_dequantize ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_finish _TEXT SEGMENT z$ = 80 stbi__jpeg_finish PROC ; COMDAT ; 2558 : { 00000 4c 8b dc mov r11, rsp 00003 41 56 push r14 00005 48 83 ec 40 sub rsp, 64 ; 00000040H ; 2559 : if (z->progressive) { 00009 83 b9 30 48 00 00 00 cmp DWORD PTR [rcx+18480], 0 00010 4c 8b f1 mov r14, rcx 00013 0f 84 b4 01 00 00 je $LN3@stbi__jpeg ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { 00019 48 8b 01 mov rax, QWORD PTR [rcx] 0001c 4d 89 6b e0 mov QWORD PTR [r11-32], r13 00020 45 33 ed xor r13d, r13d 00023 44 39 68 08 cmp DWORD PTR [rax+8], r13d 00027 0f 8e 9b 01 00 00 jle $LN54@stbi__jpeg 0002d 49 89 5b 08 mov QWORD PTR [r11+8], rbx 00031 48 8d 99 f0 46 00 00 lea rbx, QWORD PTR [rcx+18160] 00038 49 89 6b 10 mov QWORD PTR [r11+16], rbp 0003c 49 89 73 18 mov QWORD PTR [r11+24], rsi 00040 49 89 7b f0 mov QWORD PTR [r11-16], rdi 00044 4d 89 63 e8 mov QWORD PTR [r11-24], r12 00048 4d 89 7b d8 mov QWORD PTR [r11-40], r15 0004c 0f 1f 40 00 npad 4 $LL4@stbi__jpeg: ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; 00050 44 8b 7b cc mov r15d, DWORD PTR [rbx-52] 00054 33 ed xor ebp, ebp ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; 00056 44 8b 63 d0 mov r12d, DWORD PTR [rbx-48] 0005a 41 83 c7 07 add r15d, 7 0005e 41 83 c4 07 add r12d, 7 00062 41 c1 ff 03 sar r15d, 3 00066 41 c1 fc 03 sar r12d, 3 ; 2565 : for (j = 0; j < h; ++j) { 0006a 45 85 e4 test r12d, r12d 0006d 0f 8e 23 01 00 00 jle $LN2@stbi__jpeg $LL7@stbi__jpeg: ; 2566 : for (i = 0; i < w; ++i) { 00073 33 ff xor edi, edi 00075 45 85 ff test r15d, r15d 00078 0f 8e 0d 01 00 00 jle $LN5@stbi__jpeg 0007e 33 f6 xor esi, esi $LL10@stbi__jpeg: ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); 00080 4c 63 43 bc movsxd r8, DWORD PTR [rbx-68] 00084 8b c5 mov eax, ebp 00086 0f af 43 08 imul eax, DWORD PTR [rbx+8] 0008a 49 c1 e0 07 shl r8, 7 0008e 49 81 c0 88 34 00 00 add r8, 13448 ; 00003488H 00095 4d 03 c6 add r8, r14 00098 03 c7 add eax, edi 0009a c1 e0 06 shl eax, 6 0009d 48 63 c8 movsxd rcx, eax 000a0 48 8b 03 mov rax, QWORD PTR [rbx] 000a3 4c 8d 14 48 lea r10, QWORD PTR [rax+rcx*2] 000a7 49 8d 40 7e lea rax, QWORD PTR [r8+126] 000ab 49 8d 4a 7e lea rcx, QWORD PTR [r10+126] 000af 4c 3b d0 cmp r10, rax 000b2 77 37 ja SHORT $LN28@stbi__jpeg ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); 000b4 49 3b c8 cmp rcx, r8 000b7 72 32 jb SHORT $LN28@stbi__jpeg 000b9 49 8b c2 mov rax, r10 000bc 4d 2b c2 sub r8, r10 000bf 41 b9 40 00 00 00 mov r9d, 64 ; 00000040H 000c5 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL42@stbi__jpeg: ; 2554 : data[i] *= dequant[i]; 000d0 42 0f bf 0c 00 movsx ecx, WORD PTR [rax+r8] 000d5 0f bf 10 movsx edx, WORD PTR [rax] 000d8 48 8d 40 02 lea rax, QWORD PTR [rax+2] 000dc 0f af d1 imul edx, ecx 000df 66 89 50 fe mov WORD PTR [rax-2], dx 000e3 49 83 e9 01 sub r9, 1 000e7 75 e7 jne SHORT $LL42@stbi__jpeg ; 2553 : for (i = 0; i < 64; ++i) 000e9 eb 72 jmp SHORT $LN15@stbi__jpeg $LN28@stbi__jpeg: ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); 000eb 49 8d 42 10 lea rax, QWORD PTR [r10+16] 000ef 4d 2b c2 sub r8, r10 000f2 b9 02 00 00 00 mov ecx, 2 000f7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL16@stbi__jpeg: ; 2554 : data[i] *= dequant[i]; 00100 f3 0f 6f 40 f0 movdqu xmm0, XMMWORD PTR [rax-16] 00105 f3 41 0f 6f 4c 00 f0 movdqu xmm1, XMMWORD PTR [r8+rax-16] 0010c f3 41 0f 6f 14 00 movdqu xmm2, XMMWORD PTR [r8+rax] 00112 48 8d 40 40 lea rax, QWORD PTR [rax+64] 00116 66 0f d5 c8 pmullw xmm1, xmm0 0011a f3 0f 7f 48 b0 movdqu XMMWORD PTR [rax-80], xmm1 0011f f3 0f 6f 40 c0 movdqu xmm0, XMMWORD PTR [rax-64] 00124 f3 41 0f 6f 4c 00 d0 movdqu xmm1, XMMWORD PTR [r8+rax-48] 0012b 66 0f d5 d0 pmullw xmm2, xmm0 0012f f3 0f 7f 50 c0 movdqu XMMWORD PTR [rax-64], xmm2 00134 f3 0f 6f 40 d0 movdqu xmm0, XMMWORD PTR [rax-48] 00139 66 0f d5 c8 pmullw xmm1, xmm0 0013d f3 0f 7f 48 d0 movdqu XMMWORD PTR [rax-48], xmm1 00142 f3 0f 6f 40 e0 movdqu xmm0, XMMWORD PTR [rax-32] 00147 f3 41 0f 6f 4c 00 e0 movdqu xmm1, XMMWORD PTR [r8+rax-32] 0014e 66 0f d5 c8 pmullw xmm1, xmm0 00152 f3 0f 7f 48 e0 movdqu XMMWORD PTR [rax-32], xmm1 00157 48 83 e9 01 sub rcx, 1 0015b 75 a3 jne SHORT $LL16@stbi__jpeg $LN15@stbi__jpeg: ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); 0015d 8b 53 d4 mov edx, DWORD PTR [rbx-44] 00160 4d 8b c2 mov r8, r10 00163 8b c2 mov eax, edx 00165 0f af c5 imul eax, ebp 00168 c1 e0 03 shl eax, 3 0016b 48 63 c8 movsxd rcx, eax 0016e 48 03 4b e0 add rcx, QWORD PTR [rbx-32] 00172 48 03 ce add rcx, rsi 00175 41 ff 96 70 48 00 00 call QWORD PTR [r14+18544] 0017c ff c7 inc edi 0017e 48 83 c6 08 add rsi, 8 00182 41 3b ff cmp edi, r15d 00185 0f 8c f5 fe ff ff jl $LL10@stbi__jpeg $LN5@stbi__jpeg: ; 2565 : for (j = 0; j < h; ++j) { 0018b ff c5 inc ebp 0018d 41 3b ec cmp ebp, r12d 00190 0f 8c dd fe ff ff jl $LL7@stbi__jpeg $LN2@stbi__jpeg: ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { 00196 49 8b 06 mov rax, QWORD PTR [r14] 00199 41 ff c5 inc r13d 0019c 48 83 c3 60 add rbx, 96 ; 00000060H 001a0 44 3b 68 08 cmp r13d, DWORD PTR [rax+8] 001a4 0f 8c a6 fe ff ff jl $LL4@stbi__jpeg 001aa 4c 8b 7c 24 20 mov r15, QWORD PTR [rsp+32] 001af 4c 8b 64 24 30 mov r12, QWORD PTR [rsp+48] 001b4 48 8b 7c 24 38 mov rdi, QWORD PTR [rsp+56] 001b9 48 8b 74 24 60 mov rsi, QWORD PTR [rsp+96] 001be 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 001c3 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] $LN54@stbi__jpeg: 001c8 4c 8b 6c 24 28 mov r13, QWORD PTR [rsp+40] $LN3@stbi__jpeg: ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } 001cd 48 83 c4 40 add rsp, 64 ; 00000040H 001d1 41 5e pop r14 001d3 c3 ret 0 stbi__jpeg_finish ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__process_marker _TEXT SEGMENT L$3$ = 32 sizes$9 = 48 __$ArrayPad$ = 112 z$ = 176 m$ = 184 stbi__process_marker PROC ; COMDAT ; 2577 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 0000a 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi 0000f 57 push rdi 00010 41 54 push r12 00012 41 55 push r13 00014 41 56 push r14 00016 41 57 push r15 00018 48 81 ec 80 00 00 00 sub rsp, 128 ; 00000080H 0001f 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00026 48 33 c4 xor rax, rsp 00029 48 89 44 24 70 mov QWORD PTR __$ArrayPad$[rsp], rax 0002e 48 8b f1 mov rsi, rcx 00031 8b fa mov edi, edx ; 2578 : int L; ; 2579 : switch (m) { 00033 8b ca mov ecx, edx 00035 81 e9 c4 00 00 00 sub ecx, 196 ; 000000c4H 0003b 0f 84 87 07 00 00 je $LN29@stbi__proc 00041 83 e9 17 sub ecx, 23 00044 0f 84 fe 05 00 00 je $LN26@stbi__proc 0004a 83 e9 02 sub ecx, 2 0004d 0f 84 a6 05 00 00 je $LN24@stbi__proc 00053 83 f9 22 cmp ecx, 34 ; 00000022H 00056 0f 84 73 05 00 00 je $LN23@stbi__proc ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { 0005c 8d 82 20 ff ff ff lea eax, DWORD PTR [rdx-224] 00062 83 f8 0f cmp eax, 15 00065 76 32 jbe SHORT $LN39@stbi__proc 00067 81 fa fe 00 00 00 cmp edx, 254 ; 000000feH 0006d 74 2a je SHORT $LN39@stbi__proc ; 431 : stbi__g_failure_reason = str; 0006f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00075 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0007e b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00083 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00087 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@NNGPHMMK@unknown?5marker@ 0008e 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); 00092 33 c0 xor eax, eax 00094 e9 ee 09 00 00 jmp $LN1@stbi__proc $LN39@stbi__proc: ; 2637 : L = stbi__get16be(z->s); 00099 48 8b 0e mov rcx, QWORD PTR [rsi] 0009c e8 00 00 00 00 call stbi__get16be 000a1 8b d8 mov ebx, eax ; 2638 : if (L < 2) { 000a3 83 f8 02 cmp eax, 2 000a6 7d 45 jge SHORT $LN43@stbi__proc ; 2639 : if (m == 0xFE) 000a8 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 000ae 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000b7 41 b8 00 00 00 00 mov r8d, OFFSET FLAT:stbi__g_failure_reason 000bd 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] 000c1 81 ff fe 00 00 00 cmp edi, 254 ; 000000feH 000c7 75 12 jne SHORT $LN42@stbi__proc ; 431 : stbi__g_failure_reason = str; 000c9 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0M@CICAFFCH@bad?5COM?5len@ 000d0 49 89 04 10 mov QWORD PTR [r8+rdx], rax ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); 000d4 33 c0 xor eax, eax 000d6 e9 ac 09 00 00 jmp $LN1@stbi__proc $LN42@stbi__proc: ; 431 : stbi__g_failure_reason = str; 000db 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0M@EENLKPDI@bad?5APP?5len@ 000e2 49 89 04 10 mov QWORD PTR [r8+rdx], rax ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); 000e6 33 c0 xor eax, eax 000e8 e9 9a 09 00 00 jmp $LN1@stbi__proc $LN43@stbi__proc: ; 2643 : } ; 2644 : L -= 2; 000ed 83 eb 02 sub ebx, 2 ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment 000f0 81 ff e0 00 00 00 cmp edi, 224 ; 000000e0H 000f6 0f 85 bd 01 00 00 jne $LN44@stbi__proc 000fc 83 fb 05 cmp ebx, 5 000ff 0f 8c 58 04 00 00 jl $LN50@stbi__proc ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) 00105 48 8b 3e mov rdi, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00108 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0010f 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00116 73 0f jae SHORT $LN102@stbi__proc ; 1078 : return *s->img_buffer++; 00118 0f b6 08 movzx ecx, BYTE PTR [rax] 0011b 48 ff c0 inc rax 0011e 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00125 eb 26 jmp SHORT $LN101@stbi__proc $LN102@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00127 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0012b 74 1e je SHORT $LN103@stbi__proc ; 1080 : stbi__refill_buffer(s); 0012d 48 8b cf mov rcx, rdi 00130 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00135 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0013c 0f b6 08 movzx ecx, BYTE PTR [rax] 0013f 48 ff c0 inc rax 00142 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00149 eb 02 jmp SHORT $LN101@stbi__proc $LN103@stbi__proc: ; 1082 : } ; 1083 : return 0; 0014b 32 c9 xor cl, cl $LN101@stbi__proc: ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) 0014d 48 8b 3e mov rdi, QWORD PTR [rsi] 00150 45 33 e4 xor r12d, r12d 00153 80 f9 4a cmp cl, 74 ; 0000004aH 00156 45 8b f4 mov r14d, r12d 00159 41 0f 94 c6 sete r14b ; 1077 : if (s->img_buffer < s->img_buffer_end) 0015d 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00164 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0016b 73 0f jae SHORT $LN146@stbi__proc ; 1078 : return *s->img_buffer++; 0016d 0f b6 08 movzx ecx, BYTE PTR [rax] 00170 48 ff c0 inc rax 00173 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0017a eb 26 jmp SHORT $LN148@stbi__proc $LN146@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0017c 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00180 74 1e je SHORT $LN147@stbi__proc ; 1080 : stbi__refill_buffer(s); 00182 48 8b cf mov rcx, rdi 00185 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0018a 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00191 0f b6 08 movzx ecx, BYTE PTR [rax] 00194 48 ff c0 inc rax 00197 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0019e eb 02 jmp SHORT $LN148@stbi__proc $LN147@stbi__proc: ; 1082 : } ; 1083 : return 0; 001a0 32 c9 xor cl, cl $LN148@stbi__proc: ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) 001a2 48 8b 3e mov rdi, QWORD PTR [rsi] 001a5 80 f9 46 cmp cl, 70 ; 00000046H 001a8 41 8b ec mov ebp, r12d 001ab 41 0f 44 ee cmove ebp, r14d ; 1077 : if (s->img_buffer < s->img_buffer_end) 001af 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 001b6 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 001bd 73 0f jae SHORT $LN151@stbi__proc ; 1078 : return *s->img_buffer++; 001bf 0f b6 08 movzx ecx, BYTE PTR [rax] 001c2 48 ff c0 inc rax 001c5 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 001cc eb 26 jmp SHORT $LN153@stbi__proc $LN151@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 001ce 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 001d2 74 1e je SHORT $LN152@stbi__proc ; 1080 : stbi__refill_buffer(s); 001d4 48 8b cf mov rcx, rdi 001d7 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001dc 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 001e3 0f b6 08 movzx ecx, BYTE PTR [rax] 001e6 48 ff c0 inc rax 001e9 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 001f0 eb 02 jmp SHORT $LN153@stbi__proc $LN152@stbi__proc: ; 1082 : } ; 1083 : return 0; 001f2 32 c9 xor cl, cl $LN153@stbi__proc: ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) 001f4 48 8b 3e mov rdi, QWORD PTR [rsi] 001f7 80 f9 49 cmp cl, 73 ; 00000049H 001fa 45 8b f4 mov r14d, r12d 001fd 44 0f 44 f5 cmove r14d, ebp ; 1077 : if (s->img_buffer < s->img_buffer_end) 00201 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00208 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0020f 73 0f jae SHORT $LN156@stbi__proc ; 1078 : return *s->img_buffer++; 00211 0f b6 08 movzx ecx, BYTE PTR [rax] 00214 48 ff c0 inc rax 00217 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0021e eb 26 jmp SHORT $LN158@stbi__proc $LN156@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00220 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00224 74 1e je SHORT $LN157@stbi__proc ; 1080 : stbi__refill_buffer(s); 00226 48 8b cf mov rcx, rdi 00229 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0022e 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00235 0f b6 08 movzx ecx, BYTE PTR [rax] 00238 48 ff c0 inc rax 0023b 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00242 eb 02 jmp SHORT $LN158@stbi__proc $LN157@stbi__proc: ; 1082 : } ; 1083 : return 0; 00244 32 c9 xor cl, cl $LN158@stbi__proc: ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) 00246 48 8b 3e mov rdi, QWORD PTR [rsi] 00249 80 f9 46 cmp cl, 70 ; 00000046H 0024c 41 8b ec mov ebp, r12d 0024f 41 0f 44 ee cmove ebp, r14d ; 1077 : if (s->img_buffer < s->img_buffer_end) 00253 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0025a 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00261 73 0f jae SHORT $LN161@stbi__proc ; 1078 : return *s->img_buffer++; 00263 0f b6 08 movzx ecx, BYTE PTR [rax] 00266 48 ff c0 inc rax 00269 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00270 eb 26 jmp SHORT $LN163@stbi__proc $LN161@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00272 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00276 74 1e je SHORT $LN162@stbi__proc ; 1080 : stbi__refill_buffer(s); 00278 48 8b cf mov rcx, rdi 0027b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00280 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00287 0f b6 08 movzx ecx, BYTE PTR [rax] 0028a 48 ff c0 inc rax 0028d 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00294 eb 02 jmp SHORT $LN163@stbi__proc $LN162@stbi__proc: ; 1082 : } ; 1083 : return 0; 00296 32 c9 xor cl, cl $LN163@stbi__proc: ; 2652 : ok = 0; ; 2653 : L -= 5; 00298 83 eb 05 sub ebx, 5 0029b 84 c9 test cl, cl 0029d 44 0f 44 e5 cmove r12d, ebp ; 2654 : if (ok) 002a1 45 85 e4 test r12d, r12d 002a4 0f 84 b3 02 00 00 je $LN50@stbi__proc ; 2655 : z->jfif = 1; 002aa c7 86 48 48 00 00 01 00 00 00 mov DWORD PTR [rsi+18504], 1 ; 2656 : } 002b4 e9 a4 02 00 00 jmp $LN50@stbi__proc $LN44@stbi__proc: ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment 002b9 81 ff ee 00 00 00 cmp edi, 238 ; 000000eeH 002bf 0f 85 98 02 00 00 jne $LN50@stbi__proc 002c5 83 fb 0c cmp ebx, 12 002c8 0f 8c 8f 02 00 00 jl $LN50@stbi__proc ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 002ce 48 8b 3e mov rdi, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 002d1 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 002d8 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 002df 73 0f jae SHORT $LN108@stbi__proc ; 1078 : return *s->img_buffer++; 002e1 0f b6 08 movzx ecx, BYTE PTR [rax] 002e4 48 ff c0 inc rax 002e7 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 002ee eb 26 jmp SHORT $LN107@stbi__proc $LN108@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 002f0 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 002f4 74 1e je SHORT $LN109@stbi__proc ; 1080 : stbi__refill_buffer(s); 002f6 48 8b cf mov rcx, rdi 002f9 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002fe 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00305 0f b6 08 movzx ecx, BYTE PTR [rax] 00308 48 ff c0 inc rax 0030b 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00312 eb 02 jmp SHORT $LN107@stbi__proc $LN109@stbi__proc: ; 1082 : } ; 1083 : return 0; 00314 32 c9 xor cl, cl $LN107@stbi__proc: ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 00316 48 8b 3e mov rdi, QWORD PTR [rsi] 00319 45 33 e4 xor r12d, r12d 0031c 80 f9 41 cmp cl, 65 ; 00000041H 0031f 45 8b f4 mov r14d, r12d 00322 41 0f 94 c6 sete r14b ; 1077 : if (s->img_buffer < s->img_buffer_end) 00326 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0032d 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00334 73 0f jae SHORT $LN166@stbi__proc ; 1078 : return *s->img_buffer++; 00336 0f b6 08 movzx ecx, BYTE PTR [rax] 00339 48 ff c0 inc rax 0033c 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00343 eb 26 jmp SHORT $LN168@stbi__proc $LN166@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00345 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00349 74 1e je SHORT $LN167@stbi__proc ; 1080 : stbi__refill_buffer(s); 0034b 48 8b cf mov rcx, rdi 0034e e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00353 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0035a 0f b6 08 movzx ecx, BYTE PTR [rax] 0035d 48 ff c0 inc rax 00360 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00367 eb 02 jmp SHORT $LN168@stbi__proc $LN167@stbi__proc: ; 1082 : } ; 1083 : return 0; 00369 32 c9 xor cl, cl $LN168@stbi__proc: ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 0036b 48 8b 3e mov rdi, QWORD PTR [rsi] 0036e 80 f9 64 cmp cl, 100 ; 00000064H 00371 41 8b ec mov ebp, r12d 00374 41 0f 44 ee cmove ebp, r14d ; 1077 : if (s->img_buffer < s->img_buffer_end) 00378 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0037f 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00386 73 0f jae SHORT $LN171@stbi__proc ; 1078 : return *s->img_buffer++; 00388 0f b6 08 movzx ecx, BYTE PTR [rax] 0038b 48 ff c0 inc rax 0038e 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00395 eb 26 jmp SHORT $LN173@stbi__proc $LN171@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00397 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 0039b 74 1e je SHORT $LN172@stbi__proc ; 1080 : stbi__refill_buffer(s); 0039d 48 8b cf mov rcx, rdi 003a0 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003a5 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 003ac 0f b6 08 movzx ecx, BYTE PTR [rax] 003af 48 ff c0 inc rax 003b2 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 003b9 eb 02 jmp SHORT $LN173@stbi__proc $LN172@stbi__proc: ; 1082 : } ; 1083 : return 0; 003bb 32 c9 xor cl, cl $LN173@stbi__proc: ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 003bd 48 8b 3e mov rdi, QWORD PTR [rsi] 003c0 80 f9 6f cmp cl, 111 ; 0000006fH 003c3 45 8b f4 mov r14d, r12d 003c6 44 0f 44 f5 cmove r14d, ebp ; 1077 : if (s->img_buffer < s->img_buffer_end) 003ca 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 003d1 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 003d8 73 0f jae SHORT $LN176@stbi__proc ; 1078 : return *s->img_buffer++; 003da 0f b6 08 movzx ecx, BYTE PTR [rax] 003dd 48 ff c0 inc rax 003e0 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 003e7 eb 26 jmp SHORT $LN178@stbi__proc $LN176@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 003e9 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 003ed 74 1e je SHORT $LN177@stbi__proc ; 1080 : stbi__refill_buffer(s); 003ef 48 8b cf mov rcx, rdi 003f2 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003f7 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 003fe 0f b6 08 movzx ecx, BYTE PTR [rax] 00401 48 ff c0 inc rax 00404 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0040b eb 02 jmp SHORT $LN178@stbi__proc $LN177@stbi__proc: ; 1082 : } ; 1083 : return 0; 0040d 32 c9 xor cl, cl $LN178@stbi__proc: ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 0040f 48 8b 3e mov rdi, QWORD PTR [rsi] 00412 80 f9 62 cmp cl, 98 ; 00000062H 00415 45 8b fc mov r15d, r12d 00418 45 0f 44 fe cmove r15d, r14d ; 1077 : if (s->img_buffer < s->img_buffer_end) 0041c 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00423 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0042a 73 0f jae SHORT $LN181@stbi__proc ; 1078 : return *s->img_buffer++; 0042c 0f b6 08 movzx ecx, BYTE PTR [rax] 0042f 48 ff c0 inc rax 00432 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00439 eb 26 jmp SHORT $LN183@stbi__proc $LN181@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0043b 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 0043f 74 1e je SHORT $LN182@stbi__proc ; 1080 : stbi__refill_buffer(s); 00441 48 8b cf mov rcx, rdi 00444 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00449 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00450 0f b6 08 movzx ecx, BYTE PTR [rax] 00453 48 ff c0 inc rax 00456 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0045d eb 02 jmp SHORT $LN183@stbi__proc $LN182@stbi__proc: ; 1082 : } ; 1083 : return 0; 0045f 32 c9 xor cl, cl $LN183@stbi__proc: ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) 00461 48 8b 3e mov rdi, QWORD PTR [rsi] 00464 80 f9 65 cmp cl, 101 ; 00000065H 00467 41 8b ec mov ebp, r12d 0046a 41 0f 44 ef cmove ebp, r15d ; 1077 : if (s->img_buffer < s->img_buffer_end) 0046e 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00475 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0047c 73 0f jae SHORT $LN186@stbi__proc ; 1078 : return *s->img_buffer++; 0047e 0f b6 08 movzx ecx, BYTE PTR [rax] 00481 48 ff c0 inc rax 00484 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0048b eb 26 jmp SHORT $LN188@stbi__proc $LN186@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0048d 44 39 67 30 cmp DWORD PTR [rdi+48], r12d 00491 74 1e je SHORT $LN187@stbi__proc ; 1080 : stbi__refill_buffer(s); 00493 48 8b cf mov rcx, rdi 00496 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0049b 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 004a2 0f b6 08 movzx ecx, BYTE PTR [rax] 004a5 48 ff c0 inc rax 004a8 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 004af eb 02 jmp SHORT $LN188@stbi__proc $LN187@stbi__proc: ; 1082 : } ; 1083 : return 0; 004b1 32 c9 xor cl, cl $LN188@stbi__proc: ; 2663 : ok = 0; ; 2664 : L -= 6; 004b3 83 eb 06 sub ebx, 6 004b6 84 c9 test cl, cl 004b8 44 0f 44 e5 cmove r12d, ebp ; 2665 : if (ok) { 004bc 45 85 e4 test r12d, r12d 004bf 0f 84 98 00 00 00 je $LN50@stbi__proc ; 2666 : stbi__get8(z->s); // version 004c5 48 8b 3e mov rdi, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 004c8 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 004cf 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 004d6 73 0c jae SHORT $LN116@stbi__proc ; 1078 : return *s->img_buffer++; 004d8 48 ff c0 inc rax 004db 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 004e2 eb 15 jmp SHORT $LN117@stbi__proc $LN116@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 004e4 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 004e8 74 0f je SHORT $LN117@stbi__proc ; 1080 : stbi__refill_buffer(s); 004ea 48 8b cf mov rcx, rdi 004ed e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 004f2 48 ff 87 c0 00 00 00 inc QWORD PTR [rdi+192] $LN117@stbi__proc: ; 2667 : stbi__get16be(z->s); // flags0 004f9 48 8b 0e mov rcx, QWORD PTR [rsi] 004fc e8 00 00 00 00 call stbi__get16be ; 2668 : stbi__get16be(z->s); // flags1 00501 48 8b 0e mov rcx, QWORD PTR [rsi] 00504 e8 00 00 00 00 call stbi__get16be ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform 00509 48 8b 3e mov rdi, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0050c 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00513 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0051a 73 0f jae SHORT $LN120@stbi__proc ; 1078 : return *s->img_buffer++; 0051c 0f b6 08 movzx ecx, BYTE PTR [rax] 0051f 48 ff c0 inc rax 00522 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00529 eb 26 jmp SHORT $LN119@stbi__proc $LN120@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0052b 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0052f 74 1e je SHORT $LN121@stbi__proc ; 1080 : stbi__refill_buffer(s); 00531 48 8b cf mov rcx, rdi 00534 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00539 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00540 0f b6 08 movzx ecx, BYTE PTR [rax] 00543 48 ff c0 inc rax 00546 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0054d eb 02 jmp SHORT $LN119@stbi__proc $LN121@stbi__proc: ; 1082 : } ; 1083 : return 0; 0054f 32 c9 xor cl, cl $LN119@stbi__proc: ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform 00551 0f b6 c1 movzx eax, cl ; 2670 : L -= 6; 00554 83 eb 06 sub ebx, 6 00557 89 86 4c 48 00 00 mov DWORD PTR [rsi+18508], eax $LN50@stbi__proc: ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); 0055d 4c 8b 06 mov r8, QWORD PTR [rsi] ; 1107 : if (n == 0) return; // already there! 00560 85 db test ebx, ebx 00562 74 61 je SHORT $LN93@stbi__proc ; 1108 : if (n < 0) { 00564 79 18 jns SHORT $LN95@stbi__proc ; 1109 : s->img_buffer = s->img_buffer_end; 00566 49 8b 80 c8 00 00 00 mov rax, QWORD PTR [r8+200] 0056d 49 89 80 c0 00 00 00 mov QWORD PTR [r8+192], rax ; 2675 : return 1; 00574 b8 01 00 00 00 mov eax, 1 00579 e9 09 05 00 00 jmp $LN1@stbi__proc $LN95@stbi__proc: ; 1112 : if (s->io.read) { 0057e 49 83 78 10 00 cmp QWORD PTR [r8+16], 0 00583 74 36 je SHORT $LN206@stbi__proc ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00585 41 8b 88 c8 00 00 00 mov ecx, DWORD PTR [r8+200] 0058c 41 2b 88 c0 00 00 00 sub ecx, DWORD PTR [r8+192] ; 1114 : if (blen < n) { 00593 3b cb cmp ecx, ebx 00595 7d 24 jge SHORT $LN206@stbi__proc ; 1115 : s->img_buffer = s->img_buffer_end; 00597 49 8b 80 c8 00 00 00 mov rax, QWORD PTR [r8+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0059e 2b d9 sub ebx, ecx 005a0 49 8b 48 28 mov rcx, QWORD PTR [r8+40] 005a4 8b d3 mov edx, ebx 005a6 49 89 80 c0 00 00 00 mov QWORD PTR [r8+192], rax 005ad 41 ff 50 18 call QWORD PTR [r8+24] ; 2675 : return 1; 005b1 b8 01 00 00 00 mov eax, 1 005b6 e9 cc 04 00 00 jmp $LN1@stbi__proc $LN206@stbi__proc: ; 1120 : s->img_buffer += n; 005bb 48 63 cb movsxd rcx, ebx 005be 49 01 88 c0 00 00 00 add QWORD PTR [r8+192], rcx $LN93@stbi__proc: ; 2675 : return 1; 005c5 b8 01 00 00 00 mov eax, 1 005ca e9 b8 04 00 00 jmp $LN1@stbi__proc $LN23@stbi__proc: ; 431 : stbi__g_failure_reason = str; 005cf 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 005d5 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 005de b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 005e3 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 005e7 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@KLNDOKJD@expected?5marker@ 005ee 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN136@stbi__proc: ; 2679 : } 005f2 33 c0 xor eax, eax 005f4 e9 8e 04 00 00 jmp $LN1@stbi__proc $LN24@stbi__proc: ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); 005f9 48 8b 0e mov rcx, QWORD PTR [rsi] 005fc e8 00 00 00 00 call stbi__get16be 00601 83 f8 04 cmp eax, 4 00604 74 2a je SHORT $LN25@stbi__proc ; 431 : stbi__g_failure_reason = str; 00606 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0060c 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00615 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0061a 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0061e 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@LPHNODCG@bad?5DRI?5len@ 00625 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); 00629 33 c0 xor eax, eax 0062b e9 57 04 00 00 jmp $LN1@stbi__proc $LN25@stbi__proc: ; 2585 : z->restart_interval = stbi__get16be(z->s); 00630 48 8b 0e mov rcx, QWORD PTR [rsi] 00633 e8 00 00 00 00 call stbi__get16be 00638 89 86 68 48 00 00 mov DWORD PTR [rsi+18536], eax ; 2586 : return 1; 0063e b8 01 00 00 00 mov eax, 1 00643 e9 3f 04 00 00 jmp $LN1@stbi__proc $LN26@stbi__proc: ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; 00648 48 8b 0e mov rcx, QWORD PTR [rsi] 0064b e8 00 00 00 00 call stbi__get16be ; 2590 : while (L > 0) { 00650 45 33 e4 xor r12d, r12d 00653 44 8d 78 fe lea r15d, DWORD PTR [rax-2] 00657 45 85 ff test r15d, r15d 0065a 0f 8e 20 04 00 00 jle $LN289@stbi__proc 00660 4c 8d 2d 00 00 00 00 lea r13, OFFSET FLAT:stbi__jpeg_dezigzag 00667 66 0f 1f 84 00 00 00 00 00 npad 9 $LL4@stbi__proc: ; 2591 : int q = stbi__get8(z->s); 00670 48 8b 1e mov rbx, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00673 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0067a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00681 73 0f jae SHORT $LN63@stbi__proc ; 1078 : return *s->img_buffer++; 00683 0f b6 08 movzx ecx, BYTE PTR [rax] 00686 48 ff c0 inc rax 00689 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00690 eb 26 jmp SHORT $LN62@stbi__proc $LN63@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00692 44 39 63 30 cmp DWORD PTR [rbx+48], r12d 00696 74 1e je SHORT $LN64@stbi__proc ; 1080 : stbi__refill_buffer(s); 00698 48 8b cb mov rcx, rbx 0069b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 006a0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006a7 0f b6 08 movzx ecx, BYTE PTR [rax] 006aa 48 ff c0 inc rax 006ad 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 006b4 eb 02 jmp SHORT $LN62@stbi__proc $LN64@stbi__proc: ; 1082 : } ; 1083 : return 0; 006b6 32 c9 xor cl, cl $LN62@stbi__proc: ; 2591 : int q = stbi__get8(z->s); 006b8 0f b6 c1 movzx eax, cl ; 2592 : int p = q >> 4, sixteen = (p != 0); 006bb 8b e8 mov ebp, eax ; 2593 : int t = q & 15, i; 006bd 83 e0 0f and eax, 15 006c0 c1 ed 04 shr ebp, 4 ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); 006c3 83 fd 01 cmp ebp, 1 006c6 0f 87 d2 00 00 00 ja $LN131@stbi__proc ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); 006cc 83 f8 03 cmp eax, 3 006cf 0f 87 9f 00 00 00 ja $LN132@stbi__proc ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); 006d5 44 8b f0 mov r14d, eax 006d8 49 8b fc mov rdi, r12 006db 49 c1 e6 06 shl r14, 6 006df 90 npad 1 $LL8@stbi__proc: 006e0 48 8b 1e mov rbx, QWORD PTR [rsi] 006e3 85 ed test ebp, ebp 006e5 74 0c je SHORT $LN52@stbi__proc 006e7 48 8b cb mov rcx, rbx 006ea e8 00 00 00 00 call stbi__get16be 006ef 8b c8 mov ecx, eax 006f1 eb 48 jmp SHORT $LN53@stbi__proc $LN52@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 006f3 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006fa 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00701 73 0f jae SHORT $LN71@stbi__proc ; 1078 : return *s->img_buffer++; 00703 0f b6 08 movzx ecx, BYTE PTR [rax] 00706 48 ff c0 inc rax 00709 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00710 eb 26 jmp SHORT $LN70@stbi__proc $LN71@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00712 44 39 63 30 cmp DWORD PTR [rbx+48], r12d 00716 74 1e je SHORT $LN72@stbi__proc ; 1080 : stbi__refill_buffer(s); 00718 48 8b cb mov rcx, rbx 0071b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00720 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00727 0f b6 08 movzx ecx, BYTE PTR [rax] 0072a 48 ff c0 inc rax 0072d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00734 eb 02 jmp SHORT $LN70@stbi__proc $LN72@stbi__proc: ; 1082 : } ; 1083 : return 0; 00736 32 c9 xor cl, cl $LN70@stbi__proc: ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); 00738 0f b6 c9 movzx ecx, cl $LN53@stbi__proc: 0073b 42 0f b6 04 2f movzx eax, BYTE PTR [rdi+r13] 00740 48 ff c7 inc rdi 00743 49 03 c6 add rax, r14 00746 66 89 8c 46 88 34 00 00 mov WORD PTR [rsi+rax*2+13448], cx 0074e 48 83 ff 40 cmp rdi, 64 ; 00000040H 00752 7c 8c jl SHORT $LL8@stbi__proc ; 2599 : L -= (sixteen ? 129 : 65); 00754 85 ed test ebp, ebp 00756 b8 41 00 00 00 mov eax, 65 ; 00000041H 0075b b9 81 00 00 00 mov ecx, 129 ; 00000081H 00760 0f 45 c1 cmovne eax, ecx 00763 44 2b f8 sub r15d, eax 00766 45 85 ff test r15d, r15d 00769 0f 8f 01 ff ff ff jg $LL4@stbi__proc ; 2590 : while (L > 0) { 0076f e9 09 03 00 00 jmp $LN5@stbi__proc $LN132@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00774 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0077a 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00783 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00788 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0078c 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@CNHKKDIM@bad?5DQT?5table@ 00793 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); 00797 33 c0 xor eax, eax 00799 e9 e9 02 00 00 jmp $LN1@stbi__proc $LN131@stbi__proc: ; 431 : stbi__g_failure_reason = str; 0079e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 007a4 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 007ad b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 007b2 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 007b6 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@BOFJCHAP@bad?5DQT?5type@ 007bd 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); 007c1 33 c0 xor eax, eax 007c3 e9 bf 02 00 00 jmp $LN1@stbi__proc $LN29@stbi__proc: ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; 007c8 48 8b 0e mov rcx, QWORD PTR [rsi] 007cb e8 00 00 00 00 call stbi__get16be ; 2605 : while (L > 0) { 007d0 33 c9 xor ecx, ecx 007d2 44 8d 78 fe lea r15d, DWORD PTR [rax-2] 007d6 45 85 ff test r15d, r15d 007d9 0f 8e 98 02 00 00 jle $LN10@stbi__proc 007df 90 npad 1 $LL9@stbi__proc: ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); 007e0 48 8b 1e mov rbx, QWORD PTR [rsi] 007e3 44 8b e9 mov r13d, ecx ; 1077 : if (s->img_buffer < s->img_buffer_end) 007e6 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 007ed 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 007f4 73 0f jae SHORT $LN67@stbi__proc ; 1078 : return *s->img_buffer++; 007f6 0f b6 08 movzx ecx, BYTE PTR [rax] 007f9 48 ff c0 inc rax 007fc 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00803 eb 26 jmp SHORT $LN66@stbi__proc $LN67@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00805 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00809 74 1e je SHORT $LN68@stbi__proc ; 1080 : stbi__refill_buffer(s); 0080b 48 8b cb mov rcx, rbx 0080e e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00813 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0081a 0f b6 08 movzx ecx, BYTE PTR [rax] 0081d 48 ff c0 inc rax 00820 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00827 eb 02 jmp SHORT $LN66@stbi__proc $LN68@stbi__proc: ; 1082 : } ; 1083 : return 0; 00829 32 c9 xor cl, cl $LN66@stbi__proc: ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); 0082b 44 0f b6 f1 movzx r14d, cl ; 2609 : int tc = q >> 4; 0082f 45 8b e6 mov r12d, r14d ; 2610 : int th = q & 15; 00832 41 83 e6 0f and r14d, 15 00836 41 c1 ec 04 shr r12d, 4 ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); 0083a 41 83 fc 01 cmp r12d, 1 0083e 0f 87 71 02 00 00 ja $LN31@stbi__proc 00844 41 83 fe 03 cmp r14d, 3 00848 0f 87 67 02 00 00 ja $LN31@stbi__proc ; 2612 : for (i = 0; i < 16; ++i) { 0084e 48 8d 7c 24 30 lea rdi, QWORD PTR sizes$9[rsp] 00853 bd 10 00 00 00 mov ebp, 16 00858 0f 1f 84 00 00 00 00 00 npad 8 $LL13@stbi__proc: ; 2613 : sizes[i] = stbi__get8(z->s); 00860 48 8b 1e mov rbx, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00863 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0086a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00871 73 0f jae SHORT $LN59@stbi__proc ; 1078 : return *s->img_buffer++; 00873 0f b6 08 movzx ecx, BYTE PTR [rax] 00876 48 ff c0 inc rax 00879 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00880 eb 26 jmp SHORT $LN58@stbi__proc $LN59@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00882 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00886 74 1e je SHORT $LN60@stbi__proc ; 1080 : stbi__refill_buffer(s); 00888 48 8b cb mov rcx, rbx 0088b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00890 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00897 0f b6 08 movzx ecx, BYTE PTR [rax] 0089a 48 ff c0 inc rax 0089d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 008a4 eb 02 jmp SHORT $LN58@stbi__proc $LN60@stbi__proc: ; 1082 : } ; 1083 : return 0; 008a6 32 c9 xor cl, cl $LN58@stbi__proc: ; 2613 : sizes[i] = stbi__get8(z->s); 008a8 0f b6 c1 movzx eax, cl 008ab 89 07 mov DWORD PTR [rdi], eax ; 2614 : n += sizes[i]; 008ad 44 03 e8 add r13d, eax 008b0 48 83 c7 04 add rdi, 4 008b4 48 83 ed 01 sub rbp, 1 008b8 75 a6 jne SHORT $LL13@stbi__proc ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! 008ba 41 81 fd 00 01 00 00 cmp r13d, 256 ; 00000100H 008c1 0f 8f ee 01 00 00 jg $LN31@stbi__proc ; 2617 : L -= 17; 008c7 41 83 ef 11 sub r15d, 17 ; 2618 : if (tc == 0) { 008cb 48 8d 54 24 30 lea rdx, QWORD PTR sizes$9[rsp] 008d0 44 89 7c 24 20 mov DWORD PTR L$3$[rsp], r15d 008d5 45 8b fe mov r15d, r14d 008d8 49 69 df 90 06 00 00 imul rbx, r15, 1680 ; 00000690H 008df 48 03 de add rbx, rsi 008e2 45 85 e4 test r12d, r12d 008e5 75 18 jne SHORT $LN33@stbi__proc ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; 008e7 48 8d 4b 08 lea rcx, QWORD PTR [rbx+8] 008eb e8 00 00 00 00 call stbi__build_huffman 008f0 85 c0 test eax, eax 008f2 0f 84 fa fc ff ff je $LN136@stbi__proc ; 2620 : v = z->huff_dc[th].values; 008f8 b8 08 04 00 00 mov eax, 1032 ; 00000408H ; 2621 : } 008fd eb 19 jmp SHORT $LN34@stbi__proc $LN33@stbi__proc: ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; 008ff 48 8d 8b 48 1a 00 00 lea rcx, QWORD PTR [rbx+6728] 00906 e8 00 00 00 00 call stbi__build_huffman 0090b 85 c0 test eax, eax 0090d 0f 84 df fc ff ff je $LN136@stbi__proc ; 2624 : v = z->huff_ac[th].values; 00913 b8 48 1e 00 00 mov eax, 7752 ; 00001e48H $LN34@stbi__proc: ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) 00918 33 c9 xor ecx, ecx 0091a 49 63 ed movsxd rbp, r13d 0091d 4c 8d 34 18 lea r14, QWORD PTR [rax+rbx] 00921 8b f9 mov edi, ecx 00923 45 85 ed test r13d, r13d 00926 7e 5e jle SHORT $LN15@stbi__proc 00928 0f 1f 84 00 00 00 00 00 npad 8 $LL16@stbi__proc: ; 2627 : v[i] = stbi__get8(z->s); 00930 48 8b 1e mov rbx, QWORD PTR [rsi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00933 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0093a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00941 73 0f jae SHORT $LN55@stbi__proc ; 1078 : return *s->img_buffer++; 00943 0f b6 08 movzx ecx, BYTE PTR [rax] 00946 48 ff c0 inc rax 00949 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00950 eb 26 jmp SHORT $LN54@stbi__proc $LN55@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00952 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00956 74 1e je SHORT $LN56@stbi__proc ; 1080 : stbi__refill_buffer(s); 00958 48 8b cb mov rcx, rbx 0095b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00960 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00967 0f b6 08 movzx ecx, BYTE PTR [rax] 0096a 48 ff c0 inc rax 0096d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00974 eb 02 jmp SHORT $LN54@stbi__proc $LN56@stbi__proc: ; 1082 : } ; 1083 : return 0; 00976 32 c9 xor cl, cl $LN54@stbi__proc: ; 2627 : v[i] = stbi__get8(z->s); 00978 41 88 0c 3e mov BYTE PTR [r14+rdi], cl 0097c 48 ff c7 inc rdi 0097f 48 3b fd cmp rdi, rbp 00982 7c ac jl SHORT $LL16@stbi__proc 00984 33 c9 xor ecx, ecx $LN15@stbi__proc: ; 2628 : if (tc != 0) 00986 45 85 e4 test r12d, r12d 00989 0f 84 d7 00 00 00 je $LN76@stbi__proc ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); 0098f 4d 69 f7 90 06 00 00 imul r14, r15, 1680 ; 00000690H 00996 49 c1 e7 0a shl r15, 10 0099a 4c 8d 96 88 36 00 00 lea r10, QWORD PTR [rsi+13960] 009a1 4c 03 f6 add r14, rsi 009a4 44 8b d9 mov r11d, ecx 009a7 4d 03 d7 add r10, r15 009aa 49 8d 9e 48 1a 00 00 lea rbx, QWORD PTR [r14+6728] $LL77@stbi__proc: ; 1516 : stbi_uc fast = h->fast[i]; 009b1 0f b6 03 movzx eax, BYTE PTR [rbx] ; 1517 : fast_ac[i] = 0; 009b4 66 41 89 0a mov WORD PTR [r10], cx ; 1518 : if (fast < 255) { 009b8 3c ff cmp al, 255 ; 000000ffH 009ba 0f 83 8f 00 00 00 jae $LN75@stbi__proc ; 1519 : int rs = h->values[fast]; 009c0 46 0f b6 8c 30 48 1e 00 00 movzx r9d, BYTE PTR [rax+r14+7752] ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; 009c9 42 0f b6 bc 30 48 1f 00 00 movzx edi, BYTE PTR [rax+r14+8008] 009d2 41 8b e9 mov ebp, r9d 009d5 c1 ed 04 shr ebp, 4 009d8 41 83 e1 0f and r9d, 15 ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { 009dc 74 71 je SHORT $LN75@stbi__proc 009de 42 8d 04 0f lea eax, DWORD PTR [rdi+r9] 009e2 83 f8 09 cmp eax, 9 009e5 77 68 ja SHORT $LN75@stbi__proc ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); 009e7 8b cf mov ecx, edi 009e9 45 8b c3 mov r8d, r11d 009ec 41 d3 e0 shl r8d, cl ; 1527 : int m = 1 << (magbits - 1); 009ef b8 01 00 00 00 mov eax, 1 009f4 41 81 e0 ff 01 00 00 and r8d, 511 ; 000001ffH 009fb b9 09 00 00 00 mov ecx, 9 00a00 41 2b c9 sub ecx, r9d 00a03 41 d3 f8 sar r8d, cl 00a06 41 8d 49 ff lea ecx, DWORD PTR [r9-1] 00a0a d3 e0 shl eax, cl ; 1528 : if (k < m) k += (~0U << magbits) + 1; 00a0c 44 3b c0 cmp r8d, eax 00a0f 7d 14 jge SHORT $LN80@stbi__proc 00a11 41 8b c9 mov ecx, r9d 00a14 ba 01 00 00 00 mov edx, 1 00a19 d3 e2 shl edx, cl 00a1b b8 01 00 00 00 mov eax, 1 00a20 2b c2 sub eax, edx 00a22 44 03 c0 add r8d, eax $LN80@stbi__proc: ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) 00a25 41 8d 80 80 00 00 00 lea eax, DWORD PTR [r8+128] 00a2c 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00a31 77 1a ja SHORT $LN210@stbi__proc ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); 00a33 66 41 c1 e0 04 shl r8w, 4 00a38 66 44 03 c5 add r8w, bp 00a3c 66 41 c1 e0 04 shl r8w, 4 00a41 66 44 03 c7 add r8w, di 00a45 66 45 03 c1 add r8w, r9w 00a49 66 45 89 02 mov WORD PTR [r10], r8w $LN210@stbi__proc: ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { 00a4d 33 c9 xor ecx, ecx $LN75@stbi__proc: 00a4f 41 ff c3 inc r11d 00a52 48 ff c3 inc rbx 00a55 49 83 c2 02 add r10, 2 00a59 41 81 fb 00 02 00 00 cmp r11d, 512 ; 00000200H 00a60 0f 8c 4b ff ff ff jl $LL77@stbi__proc $LN76@stbi__proc: ; 2630 : L -= n; 00a66 44 8b 7c 24 20 mov r15d, DWORD PTR L$3$[rsp] 00a6b 45 2b fd sub r15d, r13d 00a6e 45 85 ff test r15d, r15d 00a71 0f 8f 69 fd ff ff jg $LL9@stbi__proc $LN10@stbi__proc: ; 2631 : } ; 2632 : return L == 0; 00a77 41 bc 00 00 00 00 mov r12d, 0 $LN5@stbi__proc: ; 2679 : } 00a7d 45 85 ff test r15d, r15d $LN289@stbi__proc: 00a80 41 0f 94 c4 sete r12b 00a84 41 8b c4 mov eax, r12d $LN1@stbi__proc: 00a87 48 8b 4c 24 70 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00a8c 48 33 cc xor rcx, rsp 00a8f e8 00 00 00 00 call __security_check_cookie 00a94 4c 8d 9c 24 80 00 00 00 lea r11, QWORD PTR [rsp+128] 00a9c 49 8b 5b 38 mov rbx, QWORD PTR [r11+56] 00aa0 49 8b 6b 40 mov rbp, QWORD PTR [r11+64] 00aa4 49 8b 73 48 mov rsi, QWORD PTR [r11+72] 00aa8 49 8b e3 mov rsp, r11 00aab 41 5f pop r15 00aad 41 5e pop r14 00aaf 41 5d pop r13 00ab1 41 5c pop r12 00ab3 5f pop rdi 00ab4 c3 ret 0 $LN31@stbi__proc: 00ab5 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00abb 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00ac4 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00ac9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00acd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@JLGKOCGN@bad?5DHT?5header@ 00ad4 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00ad8 33 c0 xor eax, eax 00ada eb ab jmp SHORT $LN1@stbi__proc stbi__process_marker ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__process_scan_header _TEXT SEGMENT z$ = 48 stbi__process_scan_header PROC ; COMDAT ; 2683 : { 00000 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx 00005 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H 0000f 48 8b f9 mov rdi, rcx ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); 00012 48 8b 09 mov rcx, QWORD PTR [rcx] 00015 e8 00 00 00 00 call stbi__get16be ; 2686 : z->scan_n = stbi__get8(z->s); 0001a 48 8b 1f mov rbx, QWORD PTR [rdi] 0001d 8b f0 mov esi, eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 0001f 48 8b 93 c0 00 00 00 mov rdx, QWORD PTR [rbx+192] 00026 48 3b 93 c8 00 00 00 cmp rdx, QWORD PTR [rbx+200] 0002d 73 0f jae SHORT $LN24@stbi__proc ; 1078 : return *s->img_buffer++; 0002f 0f b6 0a movzx ecx, BYTE PTR [rdx] 00032 48 ff c2 inc rdx 00035 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx 0003c eb 26 jmp SHORT $LN23@stbi__proc $LN24@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0003e 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00042 74 1e je SHORT $LN25@stbi__proc ; 1080 : stbi__refill_buffer(s); 00044 48 8b cb mov rcx, rbx 00047 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0004c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00053 0f b6 08 movzx ecx, BYTE PTR [rax] 00056 48 ff c0 inc rax 00059 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00060 eb 02 jmp SHORT $LN23@stbi__proc $LN25@stbi__proc: ; 1082 : } ; 1083 : return 0; 00062 32 c9 xor cl, cl $LN23@stbi__proc: ; 2686 : z->scan_n = stbi__get8(z->s); 00064 0f b6 c9 movzx ecx, cl 00067 89 8f 54 48 00 00 mov DWORD PTR [rdi+18516], ecx ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); 0006d 8d 41 ff lea eax, DWORD PTR [rcx-1] 00070 83 f8 03 cmp eax, 3 00073 0f 87 48 03 00 00 ja $LN9@stbi__proc 00079 48 8b 07 mov rax, QWORD PTR [rdi] 0007c 3b 48 08 cmp ecx, DWORD PTR [rax+8] 0007f 0f 8f 3c 03 00 00 jg $LN9@stbi__proc ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); 00085 8d 04 4d 06 00 00 00 lea eax, DWORD PTR [rcx*2+6] 0008c 3b f0 cmp esi, eax 0008e 74 35 je SHORT $LN10@stbi__proc ; 431 : stbi__g_failure_reason = str; 00090 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00096 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0009f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000a4 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000a8 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@GNEHAHOH@bad?5SOS?5len@ 000af 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); 000b3 33 c0 xor eax, eax ; 2720 : } 000b5 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 000ba 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] 000bf 48 83 c4 20 add rsp, 32 ; 00000020H 000c3 5f pop rdi 000c4 c3 ret 0 $LN10@stbi__proc: 000c5 48 89 6c 24 30 mov QWORD PTR [rsp+48], rbp ; 2689 : for (i = 0; i < z->scan_n; ++i) { 000ca 33 ed xor ebp, ebp 000cc 4c 89 74 24 38 mov QWORD PTR [rsp+56], r14 000d1 4c 8d b7 58 48 00 00 lea r14, QWORD PTR [rdi+18520] 000d8 0f 1f 84 00 00 00 00 00 npad 8 $LL4@stbi__proc: ; 2690 : int id = stbi__get8(z->s), which; 000e0 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 000e3 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000ea 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000f1 73 0f jae SHORT $LN32@stbi__proc ; 1078 : return *s->img_buffer++; 000f3 0f b6 08 movzx ecx, BYTE PTR [rax] 000f6 48 ff c0 inc rax 000f9 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00100 eb 26 jmp SHORT $LN31@stbi__proc $LN32@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00102 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00106 74 1e je SHORT $LN33@stbi__proc ; 1080 : stbi__refill_buffer(s); 00108 48 8b cb mov rcx, rbx 0010b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00110 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00117 0f b6 08 movzx ecx, BYTE PTR [rax] 0011a 48 ff c0 inc rax 0011d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00124 eb 02 jmp SHORT $LN31@stbi__proc $LN33@stbi__proc: ; 1082 : } ; 1083 : return 0; 00126 32 c9 xor cl, cl $LN31@stbi__proc: ; 2691 : int q = stbi__get8(z->s); 00128 48 8b 1f mov rbx, QWORD PTR [rdi] 0012b 0f b6 f1 movzx esi, cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 0012e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00135 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0013c 73 0f jae SHORT $LN36@stbi__proc ; 1078 : return *s->img_buffer++; 0013e 0f b6 08 movzx ecx, BYTE PTR [rax] 00141 48 ff c0 inc rax 00144 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0014b eb 26 jmp SHORT $LN35@stbi__proc $LN36@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0014d 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00151 74 1e je SHORT $LN37@stbi__proc ; 1080 : stbi__refill_buffer(s); 00153 48 8b cb mov rcx, rbx 00156 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0015b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00162 0f b6 08 movzx ecx, BYTE PTR [rax] 00165 48 ff c0 inc rax 00168 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0016f eb 02 jmp SHORT $LN35@stbi__proc $LN37@stbi__proc: ; 1082 : } ; 1083 : return 0; 00171 32 c9 xor cl, cl $LN35@stbi__proc: ; 2692 : for (which = 0; which < z->s->img_n; ++which) 00173 48 8b 07 mov rax, QWORD PTR [rdi] 00176 33 d2 xor edx, edx 00178 44 0f b6 c9 movzx r9d, cl 0017c 45 33 c0 xor r8d, r8d 0017f 8b 48 08 mov ecx, DWORD PTR [rax+8] 00182 85 c9 test ecx, ecx 00184 7e 1b jle SHORT $LN73@stbi__proc ; 2691 : int q = stbi__get8(z->s); 00186 48 8d 87 a0 46 00 00 lea rax, QWORD PTR [rdi+18080] 0018d 0f 1f 00 npad 3 $LL7@stbi__proc: ; 2693 : if (z->img_comp[which].id == id) 00190 39 30 cmp DWORD PTR [rax], esi 00192 74 0d je SHORT $LN73@stbi__proc ; 2692 : for (which = 0; which < z->s->img_n; ++which) 00194 ff c2 inc edx 00196 49 ff c0 inc r8 00199 48 83 c0 60 add rax, 96 ; 00000060H 0019d 3b d1 cmp edx, ecx 0019f 7c ef jl SHORT $LL7@stbi__proc $LN73@stbi__proc: ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match 001a1 3b d1 cmp edx, ecx 001a3 0f 84 9d 01 00 00 je $LN64@stbi__proc ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); 001a9 4b 8d 04 40 lea rax, QWORD PTR [r8+r8*2] 001ad 41 8b c9 mov ecx, r9d 001b0 48 c1 e0 05 shl rax, 5 001b4 c1 e9 04 shr ecx, 4 001b7 89 8c 38 b0 46 00 00 mov DWORD PTR [rax+rdi+18096], ecx 001be 83 f9 03 cmp ecx, 3 001c1 0f 87 d9 01 00 00 ja $LN65@stbi__proc ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); 001c7 41 83 e1 0f and r9d, 15 001cb 44 89 8c 38 b4 46 00 00 mov DWORD PTR [rax+rdi+18100], r9d 001d3 41 83 f9 03 cmp r9d, 3 001d7 0f 87 a2 01 00 00 ja $LN66@stbi__proc ; 2698 : z->order[i] = which; 001dd 41 89 16 mov DWORD PTR [r14], edx 001e0 ff c5 inc ebp 001e2 49 83 c6 04 add r14, 4 001e6 3b af 54 48 00 00 cmp ebp, DWORD PTR [rdi+18516] 001ec 0f 8c ee fe ff ff jl $LL4@stbi__proc ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); 001f2 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 001f5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001fc 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00203 73 0f jae SHORT $LN44@stbi__proc ; 1078 : return *s->img_buffer++; 00205 0f b6 08 movzx ecx, BYTE PTR [rax] 00208 48 ff c0 inc rax 0020b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00212 eb 26 jmp SHORT $LN43@stbi__proc $LN44@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00214 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00218 74 1e je SHORT $LN45@stbi__proc ; 1080 : stbi__refill_buffer(s); 0021a 48 8b cb mov rcx, rbx 0021d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00222 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00229 0f b6 08 movzx ecx, BYTE PTR [rax] 0022c 48 ff c0 inc rax 0022f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00236 eb 02 jmp SHORT $LN43@stbi__proc $LN45@stbi__proc: ; 1082 : } ; 1083 : return 0; 00238 32 c9 xor cl, cl $LN43@stbi__proc: ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 0023a 48 8b 1f mov rbx, QWORD PTR [rdi] 0023d 0f b6 c1 movzx eax, cl 00240 89 87 34 48 00 00 mov DWORD PTR [rdi+18484], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 00246 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0024d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00254 73 0f jae SHORT $LN48@stbi__proc ; 1078 : return *s->img_buffer++; 00256 0f b6 08 movzx ecx, BYTE PTR [rax] 00259 48 ff c0 inc rax 0025c 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00263 eb 26 jmp SHORT $LN47@stbi__proc $LN48@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00265 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00269 74 1e je SHORT $LN49@stbi__proc ; 1080 : stbi__refill_buffer(s); 0026b 48 8b cb mov rcx, rbx 0026e e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00273 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0027a 0f b6 08 movzx ecx, BYTE PTR [rax] 0027d 48 ff c0 inc rax 00280 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00287 eb 02 jmp SHORT $LN47@stbi__proc $LN49@stbi__proc: ; 1082 : } ; 1083 : return 0; 00289 32 c9 xor cl, cl $LN47@stbi__proc: ; 2705 : aa = stbi__get8(z->s); 0028b 48 8b 1f mov rbx, QWORD PTR [rdi] 0028e 0f b6 c1 movzx eax, cl 00291 89 87 38 48 00 00 mov DWORD PTR [rdi+18488], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 00297 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0029e 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 002a5 73 0f jae SHORT $LN52@stbi__proc ; 1078 : return *s->img_buffer++; 002a7 0f b6 08 movzx ecx, BYTE PTR [rax] 002aa 48 ff c0 inc rax 002ad 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002b4 eb 26 jmp SHORT $LN51@stbi__proc $LN52@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 002b6 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 002ba 74 1e je SHORT $LN53@stbi__proc ; 1080 : stbi__refill_buffer(s); 002bc 48 8b cb mov rcx, rbx 002bf e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002c4 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002cb 0f b6 08 movzx ecx, BYTE PTR [rax] 002ce 48 ff c0 inc rax 002d1 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002d8 eb 02 jmp SHORT $LN51@stbi__proc $LN53@stbi__proc: ; 1082 : } ; 1083 : return 0; 002da 32 c9 xor cl, cl $LN51@stbi__proc: ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { 002dc 8b 97 34 48 00 00 mov edx, DWORD PTR [rdi+18484] 002e2 0f b6 c1 movzx eax, cl 002e5 8b c8 mov ecx, eax 002e7 83 e0 0f and eax, 15 002ea c1 e9 04 shr ecx, 4 002ed 83 bf 30 48 00 00 00 cmp DWORD PTR [rdi+18480], 0 002f4 89 8f 3c 48 00 00 mov DWORD PTR [rdi+18492], ecx 002fa 89 87 40 48 00 00 mov DWORD PTR [rdi+18496], eax 00300 74 60 je SHORT $LN15@stbi__proc ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) 00302 83 fa 3f cmp edx, 63 ; 0000003fH 00305 7f 1c jg SHORT $LN21@stbi__proc 00307 44 8b 87 38 48 00 00 mov r8d, DWORD PTR [rdi+18488] 0030e 41 83 f8 3f cmp r8d, 63 ; 0000003fH 00312 7f 0f jg SHORT $LN21@stbi__proc 00314 41 3b d0 cmp edx, r8d 00317 7f 0a jg SHORT $LN21@stbi__proc 00319 83 f9 0d cmp ecx, 13 0031c 77 05 ja SHORT $LN21@stbi__proc 0031e 83 f8 0d cmp eax, 13 00321 76 55 jbe SHORT $LN16@stbi__proc $LN21@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00323 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00329 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00332 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00337 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0033b 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07EEJOMGGP@bad?5SOS@ $LN105@stbi__proc: 00342 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN64@stbi__proc: ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); 00346 33 c0 xor eax, eax $LN104@stbi__proc: 00348 48 8b 6c 24 30 mov rbp, QWORD PTR [rsp+48] 0034d 4c 8b 74 24 38 mov r14, QWORD PTR [rsp+56] ; 2720 : } 00352 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 00357 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] 0035c 48 83 c4 20 add rsp, 32 ; 00000020H 00360 5f pop rdi 00361 c3 ret 0 $LN15@stbi__proc: ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); 00362 85 d2 test edx, edx 00364 75 bd jne SHORT $LN21@stbi__proc ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); 00366 85 c9 test ecx, ecx 00368 75 b9 jne SHORT $LN21@stbi__proc 0036a 85 c0 test eax, eax 0036c 75 b5 jne SHORT $LN21@stbi__proc ; 2715 : z->spec_end = 63; 0036e c7 87 38 48 00 00 3f 00 00 00 mov DWORD PTR [rdi+18488], 63 ; 0000003fH $LN16@stbi__proc: ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; 00378 b8 01 00 00 00 mov eax, 1 0037d eb c9 jmp SHORT $LN104@stbi__proc $LN66@stbi__proc: ; 431 : stbi__g_failure_reason = str; 0037f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00385 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0038e b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00393 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00397 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@JGMCBLGG@bad?5AC?5huff@ ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); 0039e eb a2 jmp SHORT $LN105@stbi__proc $LN65@stbi__proc: ; 431 : stbi__g_failure_reason = str; 003a0 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 003a6 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 003af b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 003b4 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 003b8 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@NOCCBFAC@bad?5DC?5huff@ ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); 003bf eb 81 jmp SHORT $LN105@stbi__proc $LN9@stbi__proc: ; 431 : stbi__g_failure_reason = str; 003c1 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 003c7 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 ; 2720 : } 003d0 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 003d5 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] ; 431 : stbi__g_failure_reason = str; 003da b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 003df 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 003e3 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BI@DHFJCMBA@bad?5SOS?5component?5count@ 003ea 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); 003ee 33 c0 xor eax, eax ; 2720 : } 003f0 48 83 c4 20 add rsp, 32 ; 00000020H 003f4 5f pop rdi 003f5 c3 ret 0 stbi__process_scan_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__free_jpeg_components _TEXT SEGMENT z$ = 48 ncomp$ = 56 why$ = 64 stbi__free_jpeg_components PROC ; COMDAT ; 2723 : { 00000 40 56 push rsi 00002 48 83 ec 20 sub rsp, 32 ; 00000020H 00006 41 8b f0 mov esi, r8d ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { 00009 85 d2 test edx, edx 0000b 7e 72 jle SHORT $LN13@stbi__free 0000d 48 89 5c 24 30 mov QWORD PTR [rsp+48], rbx 00012 48 8d 99 d8 46 00 00 lea rbx, QWORD PTR [rcx+18136] 00019 48 89 6c 24 38 mov QWORD PTR [rsp+56], rbp 0001e 33 ed xor ebp, ebp 00020 48 89 7c 24 40 mov QWORD PTR [rsp+64], rdi 00025 8b fa mov edi, edx $LL4@stbi__free: ; 2726 : if (z->img_comp[i].raw_data) { 00027 48 8b 0b mov rcx, QWORD PTR [rbx] 0002a 48 85 c9 test rcx, rcx 0002d 74 0d je SHORT $LN5@stbi__free ; 2727 : STBI_FREE(z->img_comp[i].raw_data); 0002f ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2728 : z->img_comp[i].raw_data = NULL; 00035 48 89 2b mov QWORD PTR [rbx], rbp ; 2729 : z->img_comp[i].data = NULL; 00038 48 89 6b f8 mov QWORD PTR [rbx-8], rbp $LN5@stbi__free: ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { 0003c 48 8b 4b 08 mov rcx, QWORD PTR [rbx+8] 00040 48 85 c9 test rcx, rcx 00043 74 0e je SHORT $LN6@stbi__free ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); 00045 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2733 : z->img_comp[i].raw_coeff = 0; 0004b 48 89 6b 08 mov QWORD PTR [rbx+8], rbp ; 2734 : z->img_comp[i].coeff = 0; 0004f 48 89 6b 18 mov QWORD PTR [rbx+24], rbp $LN6@stbi__free: ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { 00053 48 8b 4b 10 mov rcx, QWORD PTR [rbx+16] 00057 48 85 c9 test rcx, rcx 0005a 74 0a je SHORT $LN2@stbi__free ; 2737 : STBI_FREE(z->img_comp[i].linebuf); 0005c ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2738 : z->img_comp[i].linebuf = NULL; 00062 48 89 6b 10 mov QWORD PTR [rbx+16], rbp $LN2@stbi__free: ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { 00066 48 83 c3 60 add rbx, 96 ; 00000060H 0006a 48 83 ef 01 sub rdi, 1 0006e 75 b7 jne SHORT $LL4@stbi__free 00070 48 8b 7c 24 40 mov rdi, QWORD PTR [rsp+64] 00075 48 8b 6c 24 38 mov rbp, QWORD PTR [rsp+56] 0007a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] $LN13@stbi__free: ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } 0007f 8b c6 mov eax, esi 00081 48 83 c4 20 add rsp, 32 ; 00000020H 00085 5e pop rsi 00086 c3 ret 0 stbi__free_jpeg_components ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__process_frame_header _TEXT SEGMENT z$ = 80 scan$ = 88 stbi__process_frame_header PROC ; COMDAT ; 2745 : { 00000 89 54 24 10 mov DWORD PTR [rsp+16], edx 00004 53 push rbx 00005 55 push rbp 00006 56 push rsi 00007 57 push rdi 00008 41 57 push r15 0000a 48 83 ec 20 sub rsp, 32 ; 00000020H ; 2746 : stbi__context* s = z->s; 0000e 48 8b 19 mov rbx, QWORD PTR [rcx] 00011 4c 8b f9 mov r15, rcx ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; 00014 bd 01 00 00 00 mov ebp, 1 ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG 00019 48 8b cb mov rcx, rbx 0001c 8b f5 mov esi, ebp 0001e e8 00 00 00 00 call stbi__get16be 00023 8b f8 mov edi, eax 00025 83 f8 0b cmp eax, 11 00028 7d 30 jge SHORT $LN17@stbi__proc ; 431 : stbi__g_failure_reason = str; 0002a 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00030 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00039 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0003e 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00042 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@DOFMJEMP@bad?5SOF?5len@ 00049 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG 0004d 33 c0 xor eax, eax ; 2834 : } 0004f 48 83 c4 20 add rsp, 32 ; 00000020H 00053 41 5f pop r15 00055 5f pop rdi 00056 5e pop rsi 00057 5d pop rbp 00058 5b pop rbx 00059 c3 ret 0 $LN17@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0005a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00061 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00068 72 19 jb SHORT $LN266@stbi__proc ; 1079 : if (s->read_from_callbacks) { 0006a 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0006e 0f 84 5b 07 00 00 je $LN189@stbi__proc ; 1080 : stbi__refill_buffer(s); 00074 48 8b cb mov rcx, rbx 00077 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0007c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN266@stbi__proc: ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline 00083 0f b6 08 movzx ecx, BYTE PTR [rax] 00086 48 ff c0 inc rax 00089 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00090 80 f9 08 cmp cl, 8 00093 0f 85 36 07 00 00 jne $LN189@stbi__proc ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG 00099 48 8b cb mov rcx, rbx 0009c e8 00 00 00 00 call stbi__get16be 000a1 89 43 04 mov DWORD PTR [rbx+4], eax 000a4 85 c0 test eax, eax 000a6 75 30 jne SHORT $LN19@stbi__proc ; 431 : stbi__g_failure_reason = str; 000a8 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000ae 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000b7 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000bc 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000c0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@LNEGOMA@no?5header?5height@ 000c7 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG 000cb 33 c0 xor eax, eax ; 2834 : } 000cd 48 83 c4 20 add rsp, 32 ; 00000020H 000d1 41 5f pop r15 000d3 5f pop rdi 000d4 5e pop rsi 000d5 5d pop rbp 000d6 5b pop rbx 000d7 c3 ret 0 $LN19@stbi__proc: ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires 000d8 48 8b cb mov rcx, rbx 000db e8 00 00 00 00 call stbi__get16be 000e0 89 03 mov DWORD PTR [rbx], eax 000e2 85 c0 test eax, eax 000e4 75 30 jne SHORT $LN20@stbi__proc ; 431 : stbi__g_failure_reason = str; 000e6 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000ec 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000f5 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000fa 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000fe 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07BIDACDEF@0?5width@ 00105 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires 00109 33 c0 xor eax, eax ; 2834 : } 0010b 48 83 c4 20 add rsp, 32 ; 00000020H 0010f 41 5f pop r15 00111 5f pop rdi 00112 5e pop rsi 00113 5d pop rbp 00114 5b pop rbx 00115 c3 ret 0 $LN20@stbi__proc: ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 00116 81 7b 04 00 00 00 01 cmp DWORD PTR [rbx+4], 16777216 ; 01000000H 0011d 76 30 jbe SHORT $LN21@stbi__proc $LN267@stbi__proc: ; 2834 : } 0011f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00125 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0012e b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00133 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00137 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 0013e 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00142 33 c0 xor eax, eax 00144 48 83 c4 20 add rsp, 32 ; 00000020H 00148 41 5f pop r15 0014a 5f pop rdi 0014b 5e pop rsi 0014c 5d pop rbp 0014d 5b pop rbx 0014e c3 ret 0 $LN21@stbi__proc: ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 0014f 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 00154 77 c9 ja SHORT $LN267@stbi__proc ; 1077 : if (s->img_buffer < s->img_buffer_end) 00156 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0015d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00164 73 0f jae SHORT $LN146@stbi__proc ; 1078 : return *s->img_buffer++; 00166 0f b6 08 movzx ecx, BYTE PTR [rax] 00169 48 ff c0 inc rax 0016c 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00173 eb 26 jmp SHORT $LN145@stbi__proc $LN146@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00175 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00179 74 1e je SHORT $LN147@stbi__proc ; 1080 : stbi__refill_buffer(s); 0017b 48 8b cb mov rcx, rbx 0017e e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00183 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0018a 0f b6 08 movzx ecx, BYTE PTR [rax] 0018d 48 ff c0 inc rax 00190 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00197 eb 02 jmp SHORT $LN145@stbi__proc $LN147@stbi__proc: ; 1082 : } ; 1083 : return 0; 00199 32 c9 xor cl, cl $LN145@stbi__proc: ; 2754 : c = stbi__get8(s); 0019b 0f b6 c9 movzx ecx, cl ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); 0019e 8d 41 ff lea eax, DWORD PTR [rcx-1] 001a1 a9 fc ff ff ff test eax, -4 ; fffffffcH 001a6 0f 85 f3 05 00 00 jne $LN201@stbi__proc 001ac 83 f9 02 cmp ecx, 2 001af 0f 84 ea 05 00 00 je $LN201@stbi__proc 001b5 4c 89 64 24 50 mov QWORD PTR [rsp+80], r12 ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { 001ba 45 33 e4 xor r12d, r12d 001bd 89 4b 08 mov DWORD PTR [rbx+8], ecx 001c0 48 85 c9 test rcx, rcx 001c3 74 1b je SHORT $LN3@stbi__proc 001c5 49 8d 87 e8 46 00 00 lea rax, QWORD PTR [r15+18152] 001cc 0f 1f 40 00 npad 4 $LL4@stbi__proc: ; 2758 : z->img_comp[i].data = NULL; 001d0 4c 89 60 e8 mov QWORD PTR [rax-24], r12 ; 2759 : z->img_comp[i].linebuf = NULL; 001d4 4c 89 20 mov QWORD PTR [rax], r12 001d7 48 8d 40 60 lea rax, QWORD PTR [rax+96] 001db 48 2b ce sub rcx, rsi 001de 75 f0 jne SHORT $LL4@stbi__proc $LN3@stbi__proc: ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); 001e0 8b 43 08 mov eax, DWORD PTR [rbx+8] 001e3 8d 48 04 lea ecx, DWORD PTR [rax+4] 001e6 8d 0c 48 lea ecx, DWORD PTR [rax+rcx*2] 001e9 3b f9 cmp edi, ecx 001eb 74 35 je SHORT $LN24@stbi__proc ; 431 : stbi__g_failure_reason = str; 001ed 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001f3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001fc 4c 8b 64 24 50 mov r12, QWORD PTR [rsp+80] 00201 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00206 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0020a 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@DOFMJEMP@bad?5SOF?5len@ 00211 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); 00215 33 c0 xor eax, eax ; 2834 : } 00217 48 83 c4 20 add rsp, 32 ; 00000020H 0021b 41 5f pop r15 0021d 5f pop rdi 0021e 5e pop rsi 0021f 5d pop rbp 00220 5b pop rbx 00221 c3 ret 0 $LN24@stbi__proc: 00222 4c 89 6c 24 60 mov QWORD PTR [rsp+96], r13 ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { 00227 45 8b ec mov r13d, r12d 0022a 45 89 a7 50 48 00 00 mov DWORD PTR [r15+18512], r12d 00231 44 8b 4b 08 mov r9d, DWORD PTR [rbx+8] 00235 4c 89 74 24 68 mov QWORD PTR [rsp+104], r14 0023a 45 85 c9 test r9d, r9d 0023d 0f 8e 5d 01 00 00 jle $LN6@stbi__proc 00243 4c 8d 25 00 00 00 00 lea r12, OFFSET FLAT:?rgb@?5??stbi__process_frame_header@@9@9 0024a 4d 8d b7 a4 46 00 00 lea r14, QWORD PTR [r15+18084] 00251 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 00255 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL7@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00260 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00267 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0026e 73 0f jae SHORT $LN105@stbi__proc ; 1078 : return *s->img_buffer++; 00270 0f b6 08 movzx ecx, BYTE PTR [rax] 00273 48 ff c0 inc rax 00276 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0027d eb 25 jmp SHORT $LN104@stbi__proc $LN105@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0027f 83 3f 00 cmp DWORD PTR [rdi], 0 00282 74 1e je SHORT $LN106@stbi__proc ; 1080 : stbi__refill_buffer(s); 00284 48 8b cb mov rcx, rbx 00287 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0028c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00293 0f b6 08 movzx ecx, BYTE PTR [rax] 00296 48 ff c0 inc rax 00299 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002a0 eb 02 jmp SHORT $LN104@stbi__proc $LN106@stbi__proc: ; 1082 : } ; 1083 : return 0; 002a2 32 c9 xor cl, cl $LN104@stbi__proc: ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); 002a4 0f b6 d1 movzx edx, cl 002a7 41 89 56 fc mov DWORD PTR [r14-4], edx ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) 002ab 83 7b 08 03 cmp DWORD PTR [rbx+8], 3 002af 75 10 jne SHORT $LN25@stbi__proc 002b1 41 0f b6 04 24 movzx eax, BYTE PTR [r12] 002b6 3b d0 cmp edx, eax 002b8 75 07 jne SHORT $LN25@stbi__proc ; 2769 : ++z->rgb; 002ba 41 ff 87 50 48 00 00 inc DWORD PTR [r15+18512] $LN25@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 002c1 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002c8 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 002cf 73 0f jae SHORT $LN109@stbi__proc ; 1078 : return *s->img_buffer++; 002d1 0f b6 08 movzx ecx, BYTE PTR [rax] 002d4 48 ff c0 inc rax 002d7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002de eb 25 jmp SHORT $LN108@stbi__proc $LN109@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 002e0 83 3f 00 cmp DWORD PTR [rdi], 0 002e3 74 1e je SHORT $LN110@stbi__proc ; 1080 : stbi__refill_buffer(s); 002e5 48 8b cb mov rcx, rbx 002e8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002ed 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002f4 0f b6 08 movzx ecx, BYTE PTR [rax] 002f7 48 ff c0 inc rax 002fa 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00301 eb 02 jmp SHORT $LN108@stbi__proc $LN110@stbi__proc: ; 1082 : } ; 1083 : return 0; 00303 32 c9 xor cl, cl $LN108@stbi__proc: ; 2770 : q = stbi__get8(s); 00305 0f b6 c9 movzx ecx, cl ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); 00308 8b c1 mov eax, ecx 0030a c1 e8 04 shr eax, 4 0030d 41 89 06 mov DWORD PTR [r14], eax 00310 ff c8 dec eax 00312 83 f8 03 cmp eax, 3 00315 0f 87 66 03 00 00 ja $LN166@stbi__proc ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); 0031b 83 e1 0f and ecx, 15 0031e 41 89 4e 04 mov DWORD PTR [r14+4], ecx 00322 8d 41 ff lea eax, DWORD PTR [rcx-1] 00325 83 f8 03 cmp eax, 3 00328 0f 87 32 03 00 00 ja $LN167@stbi__proc ; 1077 : if (s->img_buffer < s->img_buffer_end) 0032e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00335 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0033c 73 13 jae SHORT $LN150@stbi__proc ; 1078 : return *s->img_buffer++; 0033e 0f b6 08 movzx ecx, BYTE PTR [rax] 00341 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 00345 48 ff c0 inc rax 00348 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0034f eb 25 jmp SHORT $LN149@stbi__proc $LN150@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00351 83 3f 00 cmp DWORD PTR [rdi], 0 00354 74 1e je SHORT $LN151@stbi__proc ; 1080 : stbi__refill_buffer(s); 00356 48 8b cb mov rcx, rbx 00359 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0035e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00365 0f b6 08 movzx ecx, BYTE PTR [rax] 00368 48 ff c0 inc rax 0036b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00372 eb 02 jmp SHORT $LN149@stbi__proc $LN151@stbi__proc: ; 1082 : } ; 1083 : return 0; 00374 32 c9 xor cl, cl $LN149@stbi__proc: ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); 00376 0f b6 c1 movzx eax, cl 00379 41 89 46 08 mov DWORD PTR [r14+8], eax 0037d 83 f8 03 cmp eax, 3 00380 0f 87 9b 02 00 00 ja $LN165@stbi__proc ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { 00386 44 8b 4b 08 mov r9d, DWORD PTR [rbx+8] 0038a 41 ff c5 inc r13d 0038d 49 ff c4 inc r12 00390 49 83 c6 60 add r14, 96 ; 00000060H 00394 45 3b e9 cmp r13d, r9d 00397 0f 8c c3 fe ff ff jl $LL7@stbi__proc ; 2827 : if (z->img_comp[i].raw_coeff == NULL) 0039d 45 33 e4 xor r12d, r12d $LN6@stbi__proc: ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; 003a0 83 7c 24 58 00 cmp DWORD PTR scan$[rsp], 0 003a5 0f 85 ea 03 00 00 jne $LN15@stbi__proc ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); 003ab 8b 0b mov ecx, DWORD PTR [rbx] 003ad 44 8b 43 04 mov r8d, DWORD PTR [rbx+4] ; 467 : if (a < 0 || b < 0) return 0; 003b1 85 c9 test ecx, ecx 003b3 0f 88 b8 03 00 00 js $LN195@stbi__proc 003b9 45 85 c0 test r8d, r8d 003bc 0f 88 af 03 00 00 js $LN195@stbi__proc ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 003c2 74 11 je SHORT $LN197@stbi__proc ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 003c4 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 003c9 99 cdq 003ca 41 f7 f8 idiv r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 003cd 3b c8 cmp ecx, eax 003cf 0f 8f 9c 03 00 00 jg $LN195@stbi__proc $LN197@stbi__proc: 003d5 41 0f af c8 imul ecx, r8d ; 467 : if (a < 0 || b < 0) return 0; 003d9 85 c9 test ecx, ecx 003db 0f 88 90 03 00 00 js $LN195@stbi__proc 003e1 45 85 c9 test r9d, r9d 003e4 0f 88 87 03 00 00 js $LN195@stbi__proc ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 003ea 74 6d je SHORT $LN12@stbi__proc ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 003ec b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 003f1 99 cdq 003f2 41 f7 f9 idiv r9d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 003f5 3b c8 cmp ecx, eax 003f7 0f 8f 74 03 00 00 jg $LN195@stbi__proc ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { 003fd 45 85 c9 test r9d, r9d 00400 7e 57 jle SHORT $LN12@stbi__proc 00402 4d 8d 87 a8 46 00 00 lea r8, QWORD PTR [r15+18088] 00409 45 8b d1 mov r10d, r9d 0040c 49 8b d0 mov rdx, r8 0040f 90 npad 1 $LL10@stbi__proc: ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; 00410 8b 42 fc mov eax, DWORD PTR [rdx-4] 00413 48 8d 52 60 lea rdx, QWORD PTR [rdx+96] ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; 00417 3b c5 cmp eax, ebp 00419 8b ce mov ecx, esi 0041b 8b 72 a0 mov esi, DWORD PTR [rdx-96] 0041e 0f 4e c5 cmovle eax, ebp 00421 3b f1 cmp esi, ecx 00423 8b e8 mov ebp, eax 00425 0f 4e f1 cmovle esi, ecx 00428 49 83 ea 01 sub r10, 1 0042c 75 e2 jne SHORT $LL10@stbi__proc 0042e 41 8b cc mov ecx, r12d $LL13@stbi__proc: ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); 00431 8b c5 mov eax, ebp 00433 99 cdq 00434 41 f7 78 fc idiv DWORD PTR [r8-4] 00438 85 d2 test edx, edx 0043a 0f 85 41 02 00 00 jne $LN166@stbi__proc ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); 00440 8b c6 mov eax, esi 00442 99 cdq 00443 41 f7 38 idiv DWORD PTR [r8] 00446 85 d2 test edx, edx 00448 0f 85 12 02 00 00 jne $LN167@stbi__proc ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { 0044e ff c1 inc ecx 00450 49 83 c0 60 add r8, 96 ; 00000060H 00454 41 3b c9 cmp ecx, r9d 00457 7c d8 jl SHORT $LL13@stbi__proc $LN12@stbi__proc: ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; 00459 33 d2 xor edx, edx 0045b 41 89 af 88 46 00 00 mov DWORD PTR [r15+18056], ebp 00462 8d 0c ed 00 00 00 00 lea ecx, DWORD PTR [rbp*8] 00469 41 89 b7 8c 46 00 00 mov DWORD PTR [r15+18060], esi 00470 44 8d 04 f5 00 00 00 00 lea r8d, DWORD PTR [rsi*8] 00478 41 89 8f 98 46 00 00 mov DWORD PTR [r15+18072], ecx 0047f 45 89 87 9c 46 00 00 mov DWORD PTR [r15+18076], r8d ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { 00486 45 8b f4 mov r14d, r12d 00489 8b 03 mov eax, DWORD PTR [rbx] 0048b ff c8 dec eax 0048d 03 c1 add eax, ecx 0048f f7 f1 div ecx 00491 33 d2 xor edx, edx 00493 41 89 87 90 46 00 00 mov DWORD PTR [r15+18064], eax 0049a 8b 43 04 mov eax, DWORD PTR [rbx+4] 0049d ff c8 dec eax 0049f 41 03 c0 add eax, r8d 004a2 41 f7 f0 div r8d 004a5 41 89 87 94 46 00 00 mov DWORD PTR [r15+18068], eax 004ac 83 7b 08 00 cmp DWORD PTR [rbx+8], 0 004b0 0f 8e df 02 00 00 jle $LN15@stbi__proc 004b6 49 8d bf bc 46 00 00 lea rdi, QWORD PTR [r15+18108] 004bd 0f 1f 00 npad 3 $LL16@stbi__proc: ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; 004c0 8b 4f e8 mov ecx, DWORD PTR [rdi-24] 004c3 33 d2 xor edx, edx ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; 004c5 44 8b 47 ec mov r8d, DWORD PTR [rdi-20] 004c9 8b c1 mov eax, ecx 004cb 0f af 03 imul eax, DWORD PTR [rbx] 004ce ff c8 dec eax 004d0 03 c5 add eax, ebp 004d2 f7 f5 div ebp 004d4 33 d2 xor edx, edx 004d6 89 07 mov DWORD PTR [rdi], eax 004d8 41 8b c0 mov eax, r8d 004db 0f af 43 04 imul eax, DWORD PTR [rbx+4] 004df ff c8 dec eax 004e1 03 c6 add eax, esi 004e3 f7 f6 div esi 004e5 89 47 04 mov DWORD PTR [rdi+4], eax ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; 004e8 41 0f af 8f 90 46 00 00 imul ecx, DWORD PTR [r15+18064] 004f0 c1 e1 03 shl ecx, 3 004f3 89 4f 08 mov DWORD PTR [rdi+8], ecx ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; 004f6 45 0f af 87 94 46 00 00 imul r8d, DWORD PTR [r15+18068] ; 2814 : z->img_comp[i].coeff = 0; 004fe 4c 89 67 34 mov QWORD PTR [rdi+52], r12 ; 2815 : z->img_comp[i].raw_coeff = 0; 00502 4c 89 67 24 mov QWORD PTR [rdi+36], r12 ; 2816 : z->img_comp[i].linebuf = NULL; 00506 4c 89 67 2c mov QWORD PTR [rdi+44], r12 0050a 41 c1 e0 03 shl r8d, 3 0050e 44 89 47 0c mov DWORD PTR [rdi+12], r8d ; 467 : if (a < 0 || b < 0) return 0; 00512 85 c9 test ecx, ecx 00514 0f 88 c7 01 00 00 js $LN193@stbi__proc 0051a 45 85 c0 test r8d, r8d 0051d 0f 88 be 01 00 00 js $LN193@stbi__proc ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00523 74 11 je SHORT $LN42@stbi__proc ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00525 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0052a 99 cdq 0052b 41 f7 f8 idiv r8d ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0052e 3b c8 cmp ecx, eax 00530 0f 8f ab 01 00 00 jg $LN193@stbi__proc $LN42@stbi__proc: ; 502 : return stbi__malloc(a * b + add); 00536 41 0f af c8 imul ecx, r8d 0053a 83 c1 0f add ecx, 15 0053d 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 00540 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); 00546 48 89 47 1c mov QWORD PTR [rdi+28], rax ; 2818 : if (z->img_comp[i].raw_data == NULL) 0054a 48 85 c0 test rax, rax 0054d 0f 84 94 01 00 00 je $LN205@stbi__proc ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); 00553 48 83 c0 0f add rax, 15 00557 48 83 e0 f0 and rax, -16 0055b 48 89 47 14 mov QWORD PTR [rdi+20], rax ; 2822 : if (z->progressive) { 0055f 41 83 bf 30 48 00 00 00 cmp DWORD PTR [r15+18480], 0 00567 0f 84 9b 00 00 00 je $LN14@stbi__proc ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; 0056d 8b 4f 08 mov ecx, DWORD PTR [rdi+8] 00570 8b c1 mov eax, ecx ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; 00572 44 8b 47 0c mov r8d, DWORD PTR [rdi+12] 00576 99 cdq 00577 83 e2 07 and edx, 7 0057a 03 c2 add eax, edx 0057c c1 f8 03 sar eax, 3 0057f 89 47 3c mov DWORD PTR [rdi+60], eax 00582 41 8b c0 mov eax, r8d 00585 99 cdq 00586 83 e2 07 and edx, 7 00589 03 c2 add eax, edx 0058b c1 f8 03 sar eax, 3 0058e 89 47 40 mov DWORD PTR [rdi+64], eax ; 467 : if (a < 0 || b < 0) return 0; 00591 85 c9 test ecx, ecx 00593 0f 88 09 01 00 00 js $LN191@stbi__proc 00599 45 85 c0 test r8d, r8d 0059c 0f 88 00 01 00 00 js $LN191@stbi__proc ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 005a2 74 11 je SHORT $LN192@stbi__proc ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 005a4 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 005a9 99 cdq 005aa 41 f7 f8 idiv r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 005ad 3b c8 cmp ecx, eax 005af 0f 8f ed 00 00 00 jg $LN191@stbi__proc $LN192@stbi__proc: 005b5 8b c1 mov eax, ecx 005b7 41 0f af c0 imul eax, r8d ; 467 : if (a < 0 || b < 0) return 0; 005bb 85 c0 test eax, eax 005bd 0f 88 df 00 00 00 js $LN191@stbi__proc ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 005c3 3d ff ff ff 3f cmp eax, 1073741823 ; 3fffffffH 005c8 0f 8f d4 00 00 00 jg $LN191@stbi__proc 005ce 03 c0 add eax, eax ; 460 : return a <= INT_MAX - b; 005d0 3d f0 ff ff 7f cmp eax, 2147483632 ; 7ffffff0H ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 005d5 0f 8f c7 00 00 00 jg $LN191@stbi__proc ; 509 : return stbi__malloc(a * b * c + add); 005db 41 0f af c8 imul ecx, r8d 005df 8d 04 4d 0f 00 00 00 lea eax, DWORD PTR [rcx*2+15] 005e6 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 005e9 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); 005ef 48 89 47 24 mov QWORD PTR [rdi+36], rax ; 2827 : if (z->img_comp[i].raw_coeff == NULL) 005f3 48 85 c0 test rax, rax 005f6 0f 84 ae 00 00 00 je $LN169@stbi__proc ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); 005fc 48 83 c0 0f add rax, 15 00600 48 83 e0 f0 and rax, -16 00604 48 89 47 34 mov QWORD PTR [rdi+52], rax $LN14@stbi__proc: ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { 00608 41 ff c6 inc r14d 0060b 48 83 c7 60 add rdi, 96 ; 00000060H 0060f 44 3b 73 08 cmp r14d, DWORD PTR [rbx+8] 00613 0f 8d 7c 01 00 00 jge $LN15@stbi__proc 00619 45 33 e4 xor r12d, r12d 0061c e9 9f fe ff ff jmp $LL16@stbi__proc $LN165@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00621 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00627 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00630 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00635 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00639 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_06LJIHDFHI@bad?5TQ@ $LN268@stbi__proc: ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); 00640 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN62@stbi__proc: 00644 33 c0 xor eax, eax $LN265@stbi__proc: 00646 4c 8b 6c 24 60 mov r13, QWORD PTR [rsp+96] 0064b 4c 8b 74 24 68 mov r14, QWORD PTR [rsp+104] 00650 4c 8b 64 24 50 mov r12, QWORD PTR [rsp+80] ; 2834 : } 00655 48 83 c4 20 add rsp, 32 ; 00000020H 00659 41 5f pop r15 0065b 5f pop rdi 0065c 5e pop rsi 0065d 5d pop rbp 0065e 5b pop rbx 0065f c3 ret 0 $LN167@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00660 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00666 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0066f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00674 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00678 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_05MPLLHCJG@bad?5V@ ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); 0067f eb bf jmp SHORT $LN268@stbi__proc $LN166@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00681 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00687 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00690 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00695 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00699 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_05BLPKENEJ@bad?5H@ ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); 006a0 eb 9e jmp SHORT $LN268@stbi__proc $LN191@stbi__proc: ; 508 : if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; 006a2 48 c7 47 24 00 00 00 00 mov QWORD PTR [rdi+36], 0 $LN169@stbi__proc: ; 431 : stbi__g_failure_reason = str; 006aa 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); 006b0 45 33 c0 xor r8d, r8d ; 431 : stbi__g_failure_reason = str; 006b3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006bc b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 006c1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006c5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 006cc 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); 006d0 41 8d 56 01 lea edx, DWORD PTR [r14+1] 006d4 49 8b cf mov rcx, r15 006d7 e8 00 00 00 00 call stbi__free_jpeg_components 006dc e9 65 ff ff ff jmp $LN265@stbi__proc $LN193@stbi__proc: ; 501 : if (!stbi__mad2sizes_valid(a, b, add)) return NULL; 006e1 4c 89 67 1c mov QWORD PTR [rdi+28], r12 ; 2818 : if (z->img_comp[i].raw_data == NULL) 006e5 eb 03 jmp SHORT $LN168@stbi__proc $LN205@stbi__proc: 006e7 45 33 e4 xor r12d, r12d $LN168@stbi__proc: ; 431 : stbi__g_failure_reason = str; 006ea 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); 006f0 41 ff c6 inc r14d ; 431 : stbi__g_failure_reason = str; 006f3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006fc b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00701 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00705 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 0070c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2725 : for (i = 0; i < ncomp; ++i) { 00710 45 85 f6 test r14d, r14d 00713 0f 8e 2b ff ff ff jle $LN62@stbi__proc 00719 49 8d 9f d8 46 00 00 lea rbx, QWORD PTR [r15+18136] 00720 41 8b fe mov edi, r14d $LL63@stbi__proc: ; 2726 : if (z->img_comp[i].raw_data) { 00723 48 8b 0b mov rcx, QWORD PTR [rbx] 00726 48 85 c9 test rcx, rcx 00729 74 0d je SHORT $LN64@stbi__proc ; 2727 : STBI_FREE(z->img_comp[i].raw_data); 0072b ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2728 : z->img_comp[i].raw_data = NULL; 00731 4c 89 23 mov QWORD PTR [rbx], r12 ; 2729 : z->img_comp[i].data = NULL; 00734 4c 89 63 f8 mov QWORD PTR [rbx-8], r12 $LN64@stbi__proc: ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { 00738 48 8b 4b 08 mov rcx, QWORD PTR [rbx+8] 0073c 48 85 c9 test rcx, rcx 0073f 74 0e je SHORT $LN65@stbi__proc ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); 00741 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2733 : z->img_comp[i].raw_coeff = 0; 00747 4c 89 63 08 mov QWORD PTR [rbx+8], r12 ; 2734 : z->img_comp[i].coeff = 0; 0074b 4c 89 63 18 mov QWORD PTR [rbx+24], r12 $LN65@stbi__proc: ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { 0074f 48 8b 4b 10 mov rcx, QWORD PTR [rbx+16] 00753 48 85 c9 test rcx, rcx 00756 74 0a je SHORT $LN61@stbi__proc ; 2737 : STBI_FREE(z->img_comp[i].linebuf); 00758 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 2738 : z->img_comp[i].linebuf = NULL; 0075e 4c 89 63 10 mov QWORD PTR [rbx+16], r12 $LN61@stbi__proc: ; 1084 : } ; 1085 : ; 1086 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1087 : // nothing ; 1088 : #else ; 1089 : stbi_inline static int stbi__at_eof(stbi__context* s) ; 1090 : { ; 1091 : if (s->io.read) { ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { 00762 48 83 c3 60 add rbx, 96 ; 00000060H 00766 48 83 ef 01 sub rdi, 1 0076a 75 b7 jne SHORT $LL63@stbi__proc ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); 0076c e9 d3 fe ff ff jmp $LN62@stbi__proc $LN195@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00771 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00777 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00780 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00785 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00789 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); 00790 e9 ab fe ff ff jmp $LN268@stbi__proc $LN15@stbi__proc: ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; 00795 b8 01 00 00 00 mov eax, 1 0079a e9 a7 fe ff ff jmp $LN265@stbi__proc $LN201@stbi__proc: ; 431 : stbi__g_failure_reason = str; 0079f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 007a5 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 007ae b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 007b3 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 007b7 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BE@DAPHADHL@bad?5component?5count@ 007be 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); 007c2 33 c0 xor eax, eax ; 2834 : } 007c4 48 83 c4 20 add rsp, 32 ; 00000020H 007c8 41 5f pop r15 007ca 5f pop rdi 007cb 5e pop rsi 007cc 5d pop rbp 007cd 5b pop rbx 007ce c3 ret 0 $LN189@stbi__proc: ; 431 : stbi__g_failure_reason = str; 007cf 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 007d5 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 007de b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 007e3 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 007e7 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@BCINMEBJ@only?58?9bit@ 007ee 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline 007f2 33 c0 xor eax, eax ; 2834 : } 007f4 48 83 c4 20 add rsp, 32 ; 00000020H 007f8 41 5f pop r15 007fa 5f pop rdi 007fb 5e pop rsi 007fc 5d pop rbp 007fd 5b pop rbx 007fe c3 ret 0 stbi__process_frame_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__decode_jpeg_header _TEXT SEGMENT z$ = 48 scan$ = 56 stbi__decode_jpeg_header PROC ; COMDAT ; 2846 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 57 push rdi 00010 48 83 ec 20 sub rsp, 32 ; 00000020H ; 2396 : x = stbi__get8(j->s); 00014 48 8b 19 mov rbx, QWORD PTR [rcx] ; 2847 : int m; ; 2848 : z->jfif = 0; 00017 33 f6 xor esi, esi 00019 89 b1 48 48 00 00 mov DWORD PTR [rcx+18504], esi 0001f 8b ea mov ebp, edx ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 00021 c7 81 4c 48 00 00 ff ff ff ff mov DWORD PTR [rcx+18508], -1 0002b 48 8b f9 mov rdi, rcx ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty 0002e c6 81 28 48 00 00 ff mov BYTE PTR [rcx+18472], 255 ; 000000ffH ; 1077 : if (s->img_buffer < s->img_buffer_end) 00035 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0003c 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00043 72 18 jb SHORT $LN159@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00045 39 73 30 cmp DWORD PTR [rbx+48], esi 00048 0f 84 f8 02 00 00 je $LN99@stbi__deco ; 1080 : stbi__refill_buffer(s); 0004e 48 8b cb mov rcx, rbx 00051 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00056 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN159@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 0005d 0f b6 08 movzx ecx, BYTE PTR [rax] 00060 48 ff c0 inc rax 00063 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0006a 80 f9 ff cmp cl, 255 ; 000000ffH 0006d 0f 85 d3 02 00 00 jne $LN99@stbi__deco $LL13@stbi__deco: ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes 00073 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00076 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0007d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00084 72 18 jb SHORT $LN160@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00086 39 73 30 cmp DWORD PTR [rbx+48], esi 00089 0f 84 b7 02 00 00 je $LN99@stbi__deco ; 1080 : stbi__refill_buffer(s); 0008f 48 8b cb mov rcx, rbx 00092 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00097 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN160@stbi__deco: ; 2398 : while (x == 0xff) 0009e 0f b6 08 movzx ecx, BYTE PTR [rax] 000a1 48 ff c0 inc rax 000a4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000ab 80 f9 ff cmp cl, 255 ; 000000ffH 000ae 74 c3 je SHORT $LL13@stbi__deco ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); 000b0 80 f9 d8 cmp cl, 216 ; 000000d8H 000b3 0f 85 8d 02 00 00 jne $LN99@stbi__deco ; 2853 : if (scan == STBI__SCAN_type) return 1; 000b9 83 fd 01 cmp ebp, 1 000bc 0f 84 7d 02 00 00 je $LN10@stbi__deco ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } 000c2 0f b6 8f 28 48 00 00 movzx ecx, BYTE PTR [rdi+18472] 000c9 80 f9 ff cmp cl, 255 ; 000000ffH 000cc 74 09 je SHORT $LN31@stbi__deco 000ce c6 87 28 48 00 00 ff mov BYTE PTR [rdi+18472], 255 ; 000000ffH 000d5 eb 7a jmp SHORT $LN28@stbi__deco $LN31@stbi__deco: ; 2396 : x = stbi__get8(j->s); 000d7 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 000da 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000e1 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000e8 72 14 jb SHORT $LN161@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 000ea 39 73 30 cmp DWORD PTR [rbx+48], esi 000ed 74 60 je SHORT $LN101@stbi__deco ; 1080 : stbi__refill_buffer(s); 000ef 48 8b cb mov rcx, rbx 000f2 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000f7 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN161@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 000fe 0f b6 08 movzx ecx, BYTE PTR [rax] 00101 48 ff c0 inc rax 00104 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0010b 80 f9 ff cmp cl, 255 ; 000000ffH 0010e 75 3f jne SHORT $LN101@stbi__deco $LL29@stbi__deco: ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes 00110 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00113 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0011a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00121 72 14 jb SHORT $LN162@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00123 39 73 30 cmp DWORD PTR [rbx+48], esi 00126 74 23 je SHORT $LN40@stbi__deco ; 1080 : stbi__refill_buffer(s); 00128 48 8b cb mov rcx, rbx 0012b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00130 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN162@stbi__deco: ; 2398 : while (x == 0xff) 00137 0f b6 08 movzx ecx, BYTE PTR [rax] 0013a 48 ff c0 inc rax 0013d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00144 80 f9 ff cmp cl, 255 ; 000000ffH 00147 74 c7 je SHORT $LL29@stbi__deco 00149 eb 06 jmp SHORT $LN28@stbi__deco $LN40@stbi__deco: ; 1083 : return 0; 0014b 32 c9 xor cl, cl ; 2400 : return x; 0014d eb 02 jmp SHORT $LN28@stbi__deco $LN101@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 0014f b1 ff mov cl, 255 ; 000000ffH $LN28@stbi__deco: ; 2854 : m = stbi__get_marker(z); 00151 0f b6 d1 movzx edx, cl ; 2855 : while (!stbi__SOF(m)) { 00154 81 fa c0 00 00 00 cmp edx, 192 ; 000000c0H 0015a 0f 84 9e 01 00 00 je $LN3@stbi__deco $LL2@stbi__deco: 00160 8d 82 3f ff ff ff lea eax, DWORD PTR [rdx-193] 00166 83 f8 01 cmp eax, 1 00169 0f 86 8f 01 00 00 jbe $LN3@stbi__deco ; 2856 : if (!stbi__process_marker(z, m)) return 0; 0016f 48 8b cf mov rcx, rdi 00172 e8 00 00 00 00 call stbi__process_marker 00177 85 c0 test eax, eax 00179 0f 84 ea 01 00 00 je $LN115@stbi__deco ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } 0017f 0f b6 8f 28 48 00 00 movzx ecx, BYTE PTR [rdi+18472] 00186 80 f9 ff cmp cl, 255 ; 000000ffH 00189 74 0c je SHORT $LN45@stbi__deco 0018b c6 87 28 48 00 00 ff mov BYTE PTR [rdi+18472], 255 ; 000000ffH 00192 e9 7a 00 00 00 jmp $LN42@stbi__deco $LN45@stbi__deco: ; 2396 : x = stbi__get8(j->s); 00197 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0019a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001a1 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 001a8 72 14 jb SHORT $LN163@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 001aa 39 73 30 cmp DWORD PTR [rbx+48], esi 001ad 74 60 je SHORT $LN103@stbi__deco ; 1080 : stbi__refill_buffer(s); 001af 48 8b cb mov rcx, rbx 001b2 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001b7 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN163@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 001be 0f b6 08 movzx ecx, BYTE PTR [rax] 001c1 48 ff c0 inc rax 001c4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001cb 80 f9 ff cmp cl, 255 ; 000000ffH 001ce 75 3f jne SHORT $LN103@stbi__deco $LL43@stbi__deco: ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes 001d0 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 001d3 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001da 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 001e1 72 14 jb SHORT $LN164@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 001e3 39 73 30 cmp DWORD PTR [rbx+48], esi 001e6 74 23 je SHORT $LN54@stbi__deco ; 1080 : stbi__refill_buffer(s); 001e8 48 8b cb mov rcx, rbx 001eb e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001f0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN164@stbi__deco: ; 2398 : while (x == 0xff) 001f7 0f b6 08 movzx ecx, BYTE PTR [rax] 001fa 48 ff c0 inc rax 001fd 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00204 80 f9 ff cmp cl, 255 ; 000000ffH 00207 74 c7 je SHORT $LL43@stbi__deco 00209 eb 06 jmp SHORT $LN42@stbi__deco $LN54@stbi__deco: ; 1083 : return 0; 0020b 32 c9 xor cl, cl ; 2400 : return x; 0020d eb 02 jmp SHORT $LN42@stbi__deco $LN103@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 0020f b1 ff mov cl, 255 ; 000000ffH $LN42@stbi__deco: ; 2857 : m = stbi__get_marker(z); 00211 0f b6 d1 movzx edx, cl ; 2858 : while (m == STBI__MARKER_none) { 00214 81 fa ff 00 00 00 cmp edx, 255 ; 000000ffH 0021a 0f 85 d2 00 00 00 jne $LN124@stbi__deco $LL4@stbi__deco: ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); 00220 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1091 : if (s->io.read) { 00223 48 39 73 10 cmp QWORD PTR [rbx+16], rsi 00227 74 14 je SHORT $LN59@stbi__deco ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 00229 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0022d ff 53 20 call QWORD PTR [rbx+32] 00230 85 c0 test eax, eax 00232 74 1d je SHORT $LN114@stbi__deco ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00234 39 73 30 cmp DWORD PTR [rbx+48], esi 00237 0f 84 e6 00 00 00 je $LN123@stbi__deco $LN59@stbi__deco: ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); 0023d 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00244 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 0024b 0f 83 d2 00 00 00 jae $LN123@stbi__deco $LN114@stbi__deco: ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } 00251 0f b6 8f 28 48 00 00 movzx ecx, BYTE PTR [rdi+18472] 00258 80 f9 ff cmp cl, 255 ; 000000ffH 0025b 74 0c je SHORT $LN66@stbi__deco 0025d c6 87 28 48 00 00 ff mov BYTE PTR [rdi+18472], 255 ; 000000ffH 00264 e9 7a 00 00 00 jmp $LN63@stbi__deco $LN66@stbi__deco: ; 2396 : x = stbi__get8(j->s); 00269 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0026c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00273 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0027a 72 14 jb SHORT $LN165@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0027c 39 73 30 cmp DWORD PTR [rbx+48], esi 0027f 74 60 je SHORT $LN105@stbi__deco ; 1080 : stbi__refill_buffer(s); 00281 48 8b cb mov rcx, rbx 00284 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00289 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN165@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 00290 0f b6 08 movzx ecx, BYTE PTR [rax] 00293 48 ff c0 inc rax 00296 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0029d 80 f9 ff cmp cl, 255 ; 000000ffH 002a0 75 3f jne SHORT $LN105@stbi__deco $LL64@stbi__deco: ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes 002a2 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 002a5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002ac 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 002b3 72 14 jb SHORT $LN166@stbi__deco ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 002b5 39 73 30 cmp DWORD PTR [rbx+48], esi 002b8 74 23 je SHORT $LN75@stbi__deco ; 1080 : stbi__refill_buffer(s); 002ba 48 8b cb mov rcx, rbx 002bd e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002c2 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN166@stbi__deco: ; 2398 : while (x == 0xff) 002c9 0f b6 08 movzx ecx, BYTE PTR [rax] 002cc 48 ff c0 inc rax 002cf 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002d6 80 f9 ff cmp cl, 255 ; 000000ffH 002d9 74 c7 je SHORT $LL64@stbi__deco 002db eb 06 jmp SHORT $LN63@stbi__deco $LN75@stbi__deco: ; 1083 : return 0; 002dd 32 c9 xor cl, cl ; 2400 : return x; 002df eb 02 jmp SHORT $LN63@stbi__deco $LN105@stbi__deco: ; 2397 : if (x != 0xff) return STBI__MARKER_none; 002e1 b1 ff mov cl, 255 ; 000000ffH $LN63@stbi__deco: ; 2861 : m = stbi__get_marker(z); 002e3 0f b6 d1 movzx edx, cl 002e6 81 fa ff 00 00 00 cmp edx, 255 ; 000000ffH 002ec 0f 84 2e ff ff ff je $LL4@stbi__deco $LN124@stbi__deco: ; 2855 : while (!stbi__SOF(m)) { 002f2 81 fa c0 00 00 00 cmp edx, 192 ; 000000c0H 002f8 0f 85 62 fe ff ff jne $LL2@stbi__deco $LN3@stbi__deco: ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); 002fe 81 fa c2 00 00 00 cmp edx, 194 ; 000000c2H 00304 8b ce mov ecx, esi ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; 00306 8b d5 mov edx, ebp 00308 0f 94 c1 sete cl 0030b 89 8f 30 48 00 00 mov DWORD PTR [rdi+18480], ecx 00311 48 8b cf mov rcx, rdi 00314 e8 00 00 00 00 call stbi__process_frame_header 00319 85 c0 test eax, eax 0031b 40 0f 95 c6 setne sil 0031f 8b c6 mov eax, esi 00321 eb 48 jmp SHORT $LN1@stbi__deco $LN123@stbi__deco: ; 431 : stbi__g_failure_reason = str; 00323 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00329 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00332 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00336 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_06IFCEAHIA@no?5SOF@ ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); 0033d eb 21 jmp SHORT $LN167@stbi__deco $LN10@stbi__deco: ; 2866 : return 1; 0033f b8 01 00 00 00 mov eax, 1 00344 eb 25 jmp SHORT $LN1@stbi__deco $LN99@stbi__deco: ; 431 : stbi__g_failure_reason = str; 00346 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0034c 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00355 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00359 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_06CLMBLEP@no?5SOI@ $LN167@stbi__deco: ; 2867 : } 00360 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00365 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN115@stbi__deco: 00369 33 c0 xor eax, eax $LN1@stbi__deco: 0036b 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00370 48 8b 6c 24 38 mov rbp, QWORD PTR [rsp+56] 00375 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 0037a 48 83 c4 20 add rsp, 32 ; 00000020H 0037e 5f pop rdi 0037f c3 ret 0 stbi__decode_jpeg_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__skip_jpeg_junk_at_end _TEXT SEGMENT j$ = 48 stbi__skip_jpeg_junk_at_end PROC ; COMDAT ; 2870 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 8b f9 mov rdi, rcx 0000d 0f 1f 00 npad 3 $LL2@stbi__skip: ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { 00010 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1091 : if (s->io.read) { 00013 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00018 74 15 je SHORT $LN12@stbi__skip ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0001a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0001e ff 53 20 call QWORD PTR [rbx+32] 00021 85 c0 test eax, eax 00023 74 1e je SHORT $LN36@stbi__skip ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00025 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00029 0f 84 e5 00 00 00 je $LN3@stbi__skip $LN12@stbi__skip: ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { 0002f 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00036 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 0003d 0f 83 d1 00 00 00 jae $LN3@stbi__skip $LN36@stbi__skip: ; 2874 : int x = stbi__get8(j->s); 00043 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00046 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0004d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00054 72 15 jb SHORT $LN52@stbi__skip ; 1079 : if (s->read_from_callbacks) { 00056 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0005a 74 b4 je SHORT $LL2@stbi__skip ; 1080 : stbi__refill_buffer(s); 0005c 48 8b cb mov rcx, rbx 0005f e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00064 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN52@stbi__skip: ; 2875 : while (x == 255) { // might be a marker 0006b 0f b6 08 movzx ecx, BYTE PTR [rax] 0006e 48 ff c0 inc rax 00071 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00078 80 f9 ff cmp cl, 255 ; 000000ffH 0007b 75 93 jne SHORT $LL2@stbi__skip 0007d 0f 1f 00 npad 3 $LL4@stbi__skip: ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; 00080 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1091 : if (s->io.read) { 00083 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00088 74 11 je SHORT $LN21@stbi__skip ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0008a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0008e ff 53 20 call QWORD PTR [rbx+32] 00091 85 c0 test eax, eax 00093 74 16 je SHORT $LN35@stbi__skip ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00095 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00099 74 79 je SHORT $LN3@stbi__skip $LN21@stbi__skip: ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; 0009b 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 000a2 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 000a9 73 69 jae SHORT $LN3@stbi__skip $LN35@stbi__skip: ; 2877 : x = stbi__get8(j->s); 000ab 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 000ae 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000b5 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000bc 73 0f jae SHORT $LN24@stbi__skip ; 1078 : return *s->img_buffer++; 000be 0f b6 08 movzx ecx, BYTE PTR [rax] 000c1 48 ff c0 inc rax 000c4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000cb eb 26 jmp SHORT $LN23@stbi__skip $LN24@stbi__skip: ; 1079 : if (s->read_from_callbacks) { 000cd 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000d1 74 1e je SHORT $LN25@stbi__skip ; 1080 : stbi__refill_buffer(s); 000d3 48 8b cb mov rcx, rbx 000d6 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000db 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000e2 0f b6 08 movzx ecx, BYTE PTR [rax] 000e5 48 ff c0 inc rax 000e8 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000ef eb 02 jmp SHORT $LN23@stbi__skip $LN25@stbi__skip: ; 1082 : } ; 1083 : return 0; 000f1 32 c9 xor cl, cl $LN23@stbi__skip: ; 2877 : x = stbi__get8(j->s); 000f3 0f b6 c1 movzx eax, cl ; 2878 : if (x != 0x00 && x != 0xff) { 000f6 84 c9 test cl, cl 000f8 0f 84 12 ff ff ff je $LL2@stbi__skip 000fe 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00103 0f 84 77 ff ff ff je $LL4@stbi__skip ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } 00109 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0010e 48 83 c4 20 add rsp, 32 ; 00000020H 00112 5f pop rdi 00113 c3 ret 0 $LN3@stbi__skip: 00114 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00119 b8 ff 00 00 00 mov eax, 255 ; 000000ffH 0011e 48 83 c4 20 add rsp, 32 ; 00000020H 00122 5f pop rdi 00123 c3 ret 0 stbi__skip_jpeg_junk_at_end ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__decode_jpeg_image _TEXT SEGMENT j$ = 48 stbi__decode_jpeg_image PROC ; COMDAT ; 2893 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; 0000a 33 c0 xor eax, eax ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; 0000c 33 d2 xor edx, edx 0000e 48 89 81 d8 46 00 00 mov QWORD PTR [rcx+18136], rax 00015 48 8b f9 mov rdi, rcx 00018 48 89 81 e0 46 00 00 mov QWORD PTR [rcx+18144], rax 0001f 48 89 81 38 47 00 00 mov QWORD PTR [rcx+18232], rax 00026 48 89 81 40 47 00 00 mov QWORD PTR [rcx+18240], rax 0002d 48 89 81 98 47 00 00 mov QWORD PTR [rcx+18328], rax 00034 48 89 81 a0 47 00 00 mov QWORD PTR [rcx+18336], rax 0003b 48 89 81 f8 47 00 00 mov QWORD PTR [rcx+18424], rax 00042 48 89 81 00 48 00 00 mov QWORD PTR [rcx+18432], rax 00049 89 81 68 48 00 00 mov DWORD PTR [rcx+18536], eax 0004f e8 00 00 00 00 call stbi__decode_jpeg_header 00054 85 c0 test eax, eax 00056 0f 84 bc 01 00 00 je $LN58@stbi__deco ; 2901 : m = stbi__get_marker(j); 0005c 48 8b cf mov rcx, rdi 0005f e8 00 00 00 00 call stbi__get_marker 00064 0f b6 c8 movzx ecx, al ; 2902 : while (!stbi__EOI(m)) { 00067 81 f9 d9 00 00 00 cmp ecx, 217 ; 000000d9H 0006d 0f 84 d7 01 00 00 je $LN79@stbi__deco $LL5@stbi__deco: ; 2903 : if (stbi__SOS(m)) { 00073 81 f9 da 00 00 00 cmp ecx, 218 ; 000000daH 00079 0f 85 4f 01 00 00 jne $LN8@stbi__deco ; 2904 : if (!stbi__process_scan_header(j)) return 0; 0007f 48 8b cf mov rcx, rdi 00082 e8 00 00 00 00 call stbi__process_scan_header 00087 85 c0 test eax, eax 00089 0f 84 89 01 00 00 je $LN58@stbi__deco ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; 0008f 48 8b cf mov rcx, rdi 00092 e8 00 00 00 00 call stbi__parse_entropy_coded_data 00097 85 c0 test eax, eax 00099 0f 84 79 01 00 00 je $LN58@stbi__deco ; 2906 : if (j->marker == STBI__MARKER_none) { 0009f 80 bf 28 48 00 00 ff cmp BYTE PTR [rdi+18472], 255 ; 000000ffH 000a6 0f 85 0a 01 00 00 jne $LN12@stbi__deco 000ac 0f 1f 40 00 npad 4 $LL22@stbi__deco: ; 2873 : while (!stbi__at_eof(j->s)) { 000b0 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1091 : if (s->io.read) { 000b3 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 000b8 74 15 je SHORT $LN32@stbi__deco ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 000ba 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 000be ff 53 20 call QWORD PTR [rbx+32] 000c1 85 c0 test eax, eax 000c3 74 1e je SHORT $LN75@stbi__deco ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 000c5 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000c9 0f 84 dc 00 00 00 je $LN23@stbi__deco $LN32@stbi__deco: ; 2873 : while (!stbi__at_eof(j->s)) { 000cf 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 000d6 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 000dd 0f 83 c8 00 00 00 jae $LN23@stbi__deco $LN75@stbi__deco: ; 2874 : int x = stbi__get8(j->s); 000e3 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 000e6 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000ed 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000f4 72 15 jb SHORT $LN105@stbi__deco ; 1079 : if (s->read_from_callbacks) { 000f6 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000fa 74 b4 je SHORT $LL22@stbi__deco ; 1080 : stbi__refill_buffer(s); 000fc 48 8b cb mov rcx, rbx 000ff e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00104 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN105@stbi__deco: ; 2875 : while (x == 255) { // might be a marker 0010b 0f b6 08 movzx ecx, BYTE PTR [rax] 0010e 48 ff c0 inc rax 00111 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00118 80 f9 ff cmp cl, 255 ; 000000ffH 0011b 75 93 jne SHORT $LL22@stbi__deco 0011d 0f 1f 00 npad 3 $LL24@stbi__deco: ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; 00120 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1091 : if (s->io.read) { 00123 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00128 74 11 je SHORT $LN41@stbi__deco ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0012a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0012e ff 53 20 call QWORD PTR [rbx+32] 00131 85 c0 test eax, eax 00133 74 16 je SHORT $LN74@stbi__deco ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00135 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00139 74 70 je SHORT $LN23@stbi__deco $LN41@stbi__deco: ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; 0013b 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00142 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 00149 73 60 jae SHORT $LN23@stbi__deco $LN74@stbi__deco: ; 2877 : x = stbi__get8(j->s); 0014b 48 8b 1f mov rbx, QWORD PTR [rdi] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0014e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00155 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0015c 73 0f jae SHORT $LN44@stbi__deco ; 1078 : return *s->img_buffer++; 0015e 0f b6 08 movzx ecx, BYTE PTR [rax] 00161 48 ff c0 inc rax 00164 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0016b eb 26 jmp SHORT $LN43@stbi__deco $LN44@stbi__deco: ; 1079 : if (s->read_from_callbacks) { 0016d 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00171 74 1e je SHORT $LN45@stbi__deco ; 1080 : stbi__refill_buffer(s); 00173 48 8b cb mov rcx, rbx 00176 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0017b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00182 0f b6 08 movzx ecx, BYTE PTR [rax] 00185 48 ff c0 inc rax 00188 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0018f eb 02 jmp SHORT $LN43@stbi__deco $LN45@stbi__deco: ; 1082 : } ; 1083 : return 0; 00191 32 c9 xor cl, cl $LN43@stbi__deco: ; 2877 : x = stbi__get8(j->s); 00193 0f b6 c1 movzx eax, cl ; 2878 : if (x != 0x00 && x != 0xff) { 00196 84 c9 test cl, cl 00198 0f 84 12 ff ff ff je $LL22@stbi__deco 0019e 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 001a3 0f 84 77 ff ff ff je $LL24@stbi__deco ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; 001a9 eb 05 jmp SHORT $LN21@stbi__deco $LN23@stbi__deco: ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); 001ab b8 ff 00 00 00 mov eax, 255 ; 000000ffH $LN21@stbi__deco: 001b0 88 87 28 48 00 00 mov BYTE PTR [rdi+18472], al $LN12@stbi__deco: ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); 001b6 48 8b cf mov rcx, rdi 001b9 e8 00 00 00 00 call stbi__get_marker 001be 0f b6 c8 movzx ecx, al ; 2911 : if (STBI__RESTART(m)) 001c1 8d 81 30 ff ff ff lea eax, DWORD PTR [rcx-208] 001c7 83 f8 07 cmp eax, 7 001ca 77 72 ja SHORT $LN15@stbi__deco ; 2912 : m = stbi__get_marker(j); ; 2913 : } 001cc eb 65 jmp SHORT $LN106@stbi__deco $LN8@stbi__deco: ; 2914 : else if (stbi__DNL(m)) { 001ce 81 f9 dc 00 00 00 cmp ecx, 220 ; 000000dcH 001d4 75 4f jne SHORT $LN14@stbi__deco ; 2915 : int Ld = stbi__get16be(j->s); 001d6 48 8b 0f mov rcx, QWORD PTR [rdi] 001d9 e8 00 00 00 00 call stbi__get16be ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); 001de 48 8b 0f mov rcx, QWORD PTR [rdi] 001e1 8b d8 mov ebx, eax 001e3 e8 00 00 00 00 call stbi__get16be ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); 001e8 83 fb 04 cmp ebx, 4 001eb 75 7e jne SHORT $LN59@stbi__deco ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); 001ed 48 8b 0f mov rcx, QWORD PTR [rdi] 001f0 3b 41 04 cmp eax, DWORD PTR [rcx+4] 001f3 74 3e je SHORT $LN106@stbi__deco ; 431 : stbi__g_failure_reason = str; 001f5 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001fb 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00204 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00209 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0020d 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@PNCLKCLJ@bad?5DNL?5height@ ; 2929 : } 00214 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN58@stbi__deco: 00218 33 c0 xor eax, eax 0021a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0021f 48 83 c4 20 add rsp, 32 ; 00000020H 00223 5f pop rdi 00224 c3 ret 0 $LN14@stbi__deco: ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; 00225 8b d1 mov edx, ecx 00227 48 8b cf mov rcx, rdi 0022a e8 00 00 00 00 call stbi__process_marker 0022f 85 c0 test eax, eax 00231 74 28 je SHORT $LN19@stbi__deco $LN106@stbi__deco: ; 2902 : while (!stbi__EOI(m)) { 00233 48 8b cf mov rcx, rdi 00236 e8 00 00 00 00 call stbi__get_marker 0023b 0f b6 c8 movzx ecx, al $LN15@stbi__deco: 0023e 81 f9 d9 00 00 00 cmp ecx, 217 ; 000000d9H 00244 0f 85 29 fe ff ff jne $LL5@stbi__deco $LN79@stbi__deco: ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) 0024a 83 bf 30 48 00 00 00 cmp DWORD PTR [rdi+18480], 0 00251 74 08 je SHORT $LN19@stbi__deco ; 2927 : stbi__jpeg_finish(j); 00253 48 8b cf mov rcx, rdi 00256 e8 00 00 00 00 call stbi__jpeg_finish $LN19@stbi__deco: ; 2928 : return 1; 0025b b8 01 00 00 00 mov eax, 1 ; 2929 : } 00260 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00265 48 83 c4 20 add rsp, 32 ; 00000020H 00269 5f pop rdi 0026a c3 ret 0 $LN59@stbi__deco: ; 431 : stbi__g_failure_reason = str; 0026b 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00271 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 ; 2929 : } 0027a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 431 : stbi__g_failure_reason = str; 0027f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00284 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00288 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@EPMOIECP@bad?5DNL?5len@ ; 2929 : } 0028f 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00293 33 c0 xor eax, eax 00295 48 83 c4 20 add rsp, 32 ; 00000020H 00299 5f pop rdi 0029a c3 ret 0 stbi__decode_jpeg_image ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT resample_row_1 _TEXT SEGMENT out$ = 8 in_near$ = 16 in_far$ = 24 w$ = 32 hs$ = 40 resample_row_1 PROC ; COMDAT ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; 00000 48 8b c2 mov rax, rdx ; 2945 : } 00003 c3 ret 0 resample_row_1 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__resample_row_v_2 _TEXT SEGMENT out$ = 16 in_near$ = 24 in_far$ = 32 w$ = 40 hs$ = 48 stbi__resample_row_v_2 PROC ; COMDAT ; 2948 : { 00000 40 53 push rbx 00002 4c 8b d2 mov r10, rdx 00005 4c 8b d9 mov r11, rcx ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) 00008 33 d2 xor edx, edx 0000a 45 85 c9 test r9d, r9d 0000d 0f 8e ac 01 00 00 jle $LN9@stbi__resa 00013 41 83 f9 10 cmp r9d, 16 00017 0f 82 a2 01 00 00 jb $LN9@stbi__resa 0001d 83 3d 00 00 00 00 02 cmp DWORD PTR __isa_available, 2 00024 0f 8c 95 01 00 00 jl $LN9@stbi__resa 0002a 49 63 c9 movsxd rcx, r9d 0002d 48 ff c9 dec rcx 00030 4a 8d 04 01 lea rax, QWORD PTR [rcx+r8] 00034 4a 8d 1c 19 lea rbx, QWORD PTR [rcx+r11] 00038 4c 3b d8 cmp r11, rax 0003b 77 09 ja SHORT $LN10@stbi__resa 0003d 49 3b d8 cmp rbx, r8 00040 0f 83 79 01 00 00 jae $LN9@stbi__resa $LN10@stbi__resa: 00046 4a 8d 04 11 lea rax, QWORD PTR [rcx+r10] 0004a 4c 3b d8 cmp r11, rax 0004d 77 09 ja SHORT $LN11@stbi__resa 0004f 49 3b da cmp rbx, r10 00052 0f 83 67 01 00 00 jae $LN9@stbi__resa $LN11@stbi__resa: 00058 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0005d 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 00062 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); 00067 66 0f 6f 1d 00 00 00 00 movdqa xmm3, XMMWORD PTR __xmm@00000003000000030000000300000003 0006f 49 8d 68 04 lea rbp, QWORD PTR [r8+4] 00073 66 0f 6f 25 00 00 00 00 movdqa xmm4, XMMWORD PTR __xmm@00000002000000020000000200000002 0007b 49 8b da mov rbx, r10 0007e 49 63 c9 movsxd rcx, r9d 00081 49 8b fb mov rdi, r11 00084 48 83 e1 f0 and rcx, -16 00088 49 2b d8 sub rbx, r8 0008b 49 2b f8 sub rdi, r8 0008e 48 c7 c6 fc ff ff ff mov rsi, -4 00095 49 2b f0 sub rsi, r8 00098 0f 1f 84 00 00 00 00 00 npad 8 $LL4@stbi__resa: 000a0 66 0f 38 31 4d fc pmovzxbd xmm1, DWORD PTR [rbp-4] 000a6 66 0f 38 31 54 2b fc pmovzxbd xmm2, DWORD PTR [rbx+rbp-4] 000ad 66 0f 38 40 d3 pmulld xmm2, xmm3 000b2 66 0f fe d1 paddd xmm2, xmm1 000b6 48 8d 6d 10 lea rbp, QWORD PTR [rbp+16] 000ba 66 0f fe d4 paddd xmm2, xmm4 000be 48 8d 04 2e lea rax, QWORD PTR [rsi+rbp] 000c2 66 0f 72 e2 02 psrad xmm2, 2 000c7 83 c2 10 add edx, 16 000ca f2 0f 70 c2 d8 pshuflw xmm0, xmm2, 216 ; 000000d8H 000cf f3 0f 70 c8 d8 pshufhw xmm1, xmm0, 216 ; 000000d8H 000d4 66 0f 70 d1 d8 pshufd xmm2, xmm1, 216 ; 000000d8H 000d9 0f 54 15 00 00 00 00 andps xmm2, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 000e0 66 0f 67 d2 packuswb xmm2, xmm2 000e4 66 0f 7e 54 2f ec movd DWORD PTR [rdi+rbp-20], xmm2 000ea 66 0f 38 31 4d f0 pmovzxbd xmm1, DWORD PTR [rbp-16] 000f0 66 0f 38 31 54 2b f0 pmovzxbd xmm2, DWORD PTR [rbx+rbp-16] 000f7 66 0f 38 40 d3 pmulld xmm2, xmm3 000fc 66 0f fe d1 paddd xmm2, xmm1 00100 66 0f fe d4 paddd xmm2, xmm4 00104 66 0f 72 e2 02 psrad xmm2, 2 00109 f2 0f 70 c2 d8 pshuflw xmm0, xmm2, 216 ; 000000d8H 0010e f3 0f 70 c8 d8 pshufhw xmm1, xmm0, 216 ; 000000d8H 00113 66 0f 70 d1 d8 pshufd xmm2, xmm1, 216 ; 000000d8H 00118 0f 54 15 00 00 00 00 andps xmm2, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 0011f 66 0f 67 d2 packuswb xmm2, xmm2 00123 66 0f 7e 54 2f f0 movd DWORD PTR [rdi+rbp-16], xmm2 00129 66 0f 38 31 4d f4 pmovzxbd xmm1, DWORD PTR [rbp-12] 0012f 66 0f 38 31 54 2b f4 pmovzxbd xmm2, DWORD PTR [rbx+rbp-12] 00136 66 0f 38 40 d3 pmulld xmm2, xmm3 0013b 66 0f fe d1 paddd xmm2, xmm1 0013f 66 0f fe d4 paddd xmm2, xmm4 00143 66 0f 72 e2 02 psrad xmm2, 2 00148 f2 0f 70 c2 d8 pshuflw xmm0, xmm2, 216 ; 000000d8H 0014d f3 0f 70 c8 d8 pshufhw xmm1, xmm0, 216 ; 000000d8H 00152 66 0f 70 d1 d8 pshufd xmm2, xmm1, 216 ; 000000d8H 00157 0f 54 15 00 00 00 00 andps xmm2, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 0015e 66 0f 67 d2 packuswb xmm2, xmm2 00162 66 0f 7e 54 2f f4 movd DWORD PTR [rdi+rbp-12], xmm2 00168 66 0f 38 31 4d f8 pmovzxbd xmm1, DWORD PTR [rbp-8] 0016e 66 0f 38 31 54 2b f8 pmovzxbd xmm2, DWORD PTR [rbx+rbp-8] 00175 66 0f 38 40 d3 pmulld xmm2, xmm3 0017a 66 0f fe d1 paddd xmm2, xmm1 0017e 66 0f fe d4 paddd xmm2, xmm4 00182 66 0f 72 e2 02 psrad xmm2, 2 00187 f2 0f 70 c2 d8 pshuflw xmm0, xmm2, 216 ; 000000d8H 0018c f3 0f 70 c8 d8 pshufhw xmm1, xmm0, 216 ; 000000d8H 00191 66 0f 70 d1 d8 pshufd xmm2, xmm1, 216 ; 000000d8H 00196 0f 54 15 00 00 00 00 andps xmm2, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff 0019d 66 0f 67 d2 packuswb xmm2, xmm2 001a1 66 0f 7e 54 2f f8 movd DWORD PTR [rdi+rbp-8], xmm2 001a7 48 3b c1 cmp rax, rcx 001aa 0f 8c f0 fe ff ff jl $LL4@stbi__resa ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) 001b0 48 8b 7c 24 20 mov rdi, QWORD PTR [rsp+32] 001b5 48 8b 74 24 18 mov rsi, QWORD PTR [rsp+24] 001ba 48 8b 6c 24 10 mov rbp, QWORD PTR [rsp+16] $LN9@stbi__resa: 001bf 48 63 ca movsxd rcx, edx 001c2 4d 63 c9 movsxd r9, r9d 001c5 49 3b c9 cmp rcx, r9 001c8 7d 3c jge SHORT $LN19@stbi__resa 001ca 49 8b db mov rbx, r11 001cd 4a 8d 04 01 lea rax, QWORD PTR [rcx+r8] 001d1 49 2b d8 sub rbx, r8 001d4 4d 2b d0 sub r10, r8 001d7 4c 2b c9 sub r9, rcx 001da 66 0f 1f 44 00 00 npad 6 $LL8@stbi__resa: ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); 001e0 42 0f b6 0c 10 movzx ecx, BYTE PTR [rax+r10] 001e5 44 0f b6 00 movzx r8d, BYTE PTR [rax] 001e9 48 8d 40 01 lea rax, QWORD PTR [rax+1] 001ed 41 83 c0 02 add r8d, 2 001f1 8d 14 49 lea edx, DWORD PTR [rcx+rcx*2] 001f4 44 03 c2 add r8d, edx 001f7 41 c1 e8 02 shr r8d, 2 001fb 44 88 44 03 ff mov BYTE PTR [rbx+rax-1], r8b 00200 49 83 e9 01 sub r9, 1 00204 75 da jne SHORT $LL8@stbi__resa $LN19@stbi__resa: ; 2954 : return out; ; 2955 : } 00206 49 8b c3 mov rax, r11 00209 5b pop rbx 0020a c3 ret 0 stbi__resample_row_v_2 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__resample_row_h_2 _TEXT SEGMENT out$ = 16 in_near$ = 24 in_far$ = 32 w$ = 40 hs$ = 48 stbi__resample_row_h_2 PROC ; COMDAT ; 2958 : { 00000 48 83 ec 08 sub rsp, 8 ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; 00004 0f b6 02 movzx eax, BYTE PTR [rdx] 00007 4c 8b da mov r11, rdx 0000a 88 01 mov BYTE PTR [rcx], al 0000c 4c 8b d1 mov r10, rcx ; 2962 : ; 2963 : if (w == 1) { 0000f 41 83 f9 01 cmp r9d, 1 00013 75 0b jne SHORT $LN5@stbi__resa ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; 00015 88 41 01 mov BYTE PTR [rcx+1], al ; 2983 : } 00018 48 8b c1 mov rax, rcx 0001b 48 83 c4 08 add rsp, 8 0001f c3 ret 0 $LN5@stbi__resa: ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); 00020 0f b6 02 movzx eax, BYTE PTR [rdx] 00023 0f b6 52 01 movzx edx, BYTE PTR [rdx+1] 00027 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 0002c 83 c2 02 add edx, 2 0002f 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi ; 2971 : for (i = 1; i < w - 1; ++i) { 00034 49 63 f1 movsxd rsi, r9d 00037 8d 0c 40 lea ecx, DWORD PTR [rax+rax*2] 0003a 03 d1 add edx, ecx 0003c 48 89 3c 24 mov QWORD PTR [rsp], rdi 00040 c1 ea 02 shr edx, 2 00043 bf 01 00 00 00 mov edi, 1 00048 41 88 52 01 mov BYTE PTR [r10+1], dl 0004c 48 8d 5e ff lea rbx, QWORD PTR [rsi-1] 00050 48 3b df cmp rbx, rdi 00053 7e 4d jle SHORT $LN3@stbi__resa 00055 4c 8d 4b ff lea r9, QWORD PTR [rbx-1] 00059 41 8d 79 01 lea edi, DWORD PTR [r9+1] 0005d 4d 8d 42 02 lea r8, QWORD PTR [r10+2] 00061 49 8d 53 02 lea rdx, QWORD PTR [r11+2] 00065 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL4@stbi__resa: ; 2972 : int n = 3 * input[i] + 2; 00070 0f b6 42 ff movzx eax, BYTE PTR [rdx-1] 00074 4d 8d 40 02 lea r8, QWORD PTR [r8+2] 00078 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 0007c 8d 48 01 lea ecx, DWORD PTR [rax+1] 0007f 8d 0c 48 lea ecx, DWORD PTR [rax+rcx*2] ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); 00082 0f b6 42 fd movzx eax, BYTE PTR [rdx-3] 00086 03 c1 add eax, ecx 00088 c1 e8 02 shr eax, 2 0008b 41 88 40 fe mov BYTE PTR [r8-2], al ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); 0008f 0f b6 42 ff movzx eax, BYTE PTR [rdx-1] 00093 03 c1 add eax, ecx 00095 c1 e8 02 shr eax, 2 00098 41 88 40 ff mov BYTE PTR [r8-1], al 0009c 49 83 e9 01 sub r9, 1 000a0 75 ce jne SHORT $LL4@stbi__resa $LN3@stbi__resa: ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); 000a2 42 0f b6 14 1b movzx edx, BYTE PTR [rbx+r11] 000a7 8d 04 3f lea eax, DWORD PTR [rdi+rdi] ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; 000aa 48 8b 3c 24 mov rdi, QWORD PTR [rsp] 000ae 83 c2 02 add edx, 2 000b1 4c 63 c0 movsxd r8, eax 000b4 42 0f b6 44 1e fe movzx eax, BYTE PTR [rsi+r11-2] 000ba 48 8b 74 24 18 mov rsi, QWORD PTR [rsp+24] 000bf 8d 0c 40 lea ecx, DWORD PTR [rax+rax*2] 000c2 03 d1 add edx, ecx 000c4 c1 ea 02 shr edx, 2 000c7 43 88 14 10 mov BYTE PTR [r8+r10], dl 000cb 42 0f b6 04 1b movzx eax, BYTE PTR [rbx+r11] 000d0 48 8b 5c 24 10 mov rbx, QWORD PTR [rsp+16] 000d5 43 88 44 10 01 mov BYTE PTR [r8+r10+1], al ; 2983 : } 000da 49 8b c2 mov rax, r10 000dd 48 83 c4 08 add rsp, 8 000e1 c3 ret 0 stbi__resample_row_h_2 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__resample_row_hv_2 _TEXT SEGMENT out$ = 16 in_near$ = 24 in_far$ = 32 w$ = 40 hs$ = 48 stbi__resample_row_hv_2 PROC ; COMDAT ; 2988 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 56 push rsi 00006 0f b6 02 movzx eax, BYTE PTR [rdx] 00009 48 8b da mov rbx, rdx 0000c 45 0f b6 10 movzx r10d, BYTE PTR [r8] 00010 4c 8b d9 mov r11, rcx 00013 49 63 f1 movsxd rsi, r9d 00016 8d 04 40 lea eax, DWORD PTR [rax+rax*2] 00019 41 03 c2 add eax, r10d ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { 0001c 83 fe 01 cmp esi, 1 0001f 75 15 jne SHORT $LN5@stbi__resa ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); 00021 83 c0 02 add eax, 2 00024 c1 e8 02 shr eax, 2 00027 88 41 01 mov BYTE PTR [rcx+1], al 0002a 88 01 mov BYTE PTR [rcx], al ; 3009 : } 0002c 48 8b c1 mov rax, rcx 0002f 48 8b 5c 24 18 mov rbx, QWORD PTR [rsp+24] 00034 5e pop rsi 00035 c3 ret 0 $LN5@stbi__resa: ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); 00036 8d 48 02 lea ecx, DWORD PTR [rax+2] 00039 48 89 7c 24 10 mov QWORD PTR [rsp+16], rdi 0003e c1 e9 02 shr ecx, 2 ; 2998 : for (i = 1; i < w; ++i) { 00041 48 8b fe mov rdi, rsi 00044 41 88 0b mov BYTE PTR [r11], cl 00047 48 83 fe 01 cmp rsi, 1 0004b 7e 53 jle SHORT $LN3@stbi__resa 0004d 49 2b d8 sub rbx, r8 00050 4d 8d 48 01 lea r9, QWORD PTR [r8+1] 00054 48 ff cf dec rdi 00057 4d 8d 53 02 lea r10, QWORD PTR [r11+2] 0005b 0f 1f 44 00 00 npad 5 $LL4@stbi__resa: ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; 00060 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00064 4d 8d 52 02 lea r10, QWORD PTR [r10+2] 00068 44 8b c0 mov r8d, eax 0006b 41 0f b6 04 19 movzx eax, BYTE PTR [r9+rbx] 00070 4d 8d 49 01 lea r9, QWORD PTR [r9+1] 00074 8d 04 40 lea eax, DWORD PTR [rax+rax*2] 00077 03 c1 add eax, ecx ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); 00079 41 8d 50 04 lea edx, DWORD PTR [r8+4] 0007d 8d 14 50 lea edx, DWORD PTR [rax+rdx*2] 00080 41 03 d0 add edx, r8d 00083 c1 ea 04 shr edx, 4 00086 41 88 52 fd mov BYTE PTR [r10-3], dl ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); 0008a 8d 50 04 lea edx, DWORD PTR [rax+4] 0008d 41 8d 14 50 lea edx, DWORD PTR [r8+rdx*2] 00091 03 d0 add edx, eax 00093 c1 ea 04 shr edx, 4 00096 41 88 52 fe mov BYTE PTR [r10-2], dl 0009a 48 83 ef 01 sub rdi, 1 0009e 75 c0 jne SHORT $LL4@stbi__resa $LN3@stbi__resa: ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; 000a0 48 8b 7c 24 10 mov rdi, QWORD PTR [rsp+16] 000a5 8d 50 02 lea edx, DWORD PTR [rax+2] ; 3009 : } 000a8 48 8b 5c 24 18 mov rbx, QWORD PTR [rsp+24] 000ad 8d 04 36 lea eax, DWORD PTR [rsi+rsi] 000b0 48 63 c8 movsxd rcx, eax 000b3 49 8b c3 mov rax, r11 000b6 c1 ea 02 shr edx, 2 000b9 42 88 54 19 ff mov BYTE PTR [rcx+r11-1], dl 000be 5e pop rsi 000bf c3 ret 0 stbi__resample_row_hv_2 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__resample_row_hv_2_simd _TEXT SEGMENT out$ = 24 in_near$ = 32 in_far$ = 40 w$ = 48 hs$ = 56 stbi__resample_row_hv_2_simd PROC ; COMDAT ; 3013 : { 00000 40 56 push rsi 00002 57 push rdi ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; 00003 0f b6 02 movzx eax, BYTE PTR [rdx] 00006 4d 8b d0 mov r10, r8 00009 49 63 f1 movsxd rsi, r9d 0000c 48 8b f9 mov rdi, rcx 0000f 45 33 c9 xor r9d, r9d 00012 44 8d 04 40 lea r8d, DWORD PTR [rax+rax*2] 00016 41 0f b6 02 movzx eax, BYTE PTR [r10] 0001a 44 03 c0 add r8d, eax ; 3016 : ; 3017 : if (w == 1) { 0001d 83 fe 01 cmp esi, 1 00020 75 12 jne SHORT $LN8@stbi__resa ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); 00022 41 8d 40 02 lea eax, DWORD PTR [r8+2] 00026 c1 e8 02 shr eax, 2 00029 88 41 01 mov BYTE PTR [rcx+1], al 0002c 88 01 mov BYTE PTR [rcx], al ; 3125 : } 0002e 48 8b c1 mov rax, rcx 00031 5f pop rdi 00032 5e pop rsi 00033 c3 ret 0 $LN8@stbi__resa: 00034 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { 00039 8d 46 ff lea eax, DWORD PTR [rsi-1] 0003c 48 8b da mov rbx, rdx 0003f 83 e0 f8 and eax, -8 00042 49 2b da sub rbx, r10 00045 85 c0 test eax, eax 00047 0f 8e 02 01 00 00 jle $LN18@stbi__resa ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); 0004d 66 0f 6f 2d 00 00 00 00 movdqa xmm5, XMMWORD PTR __xmm@00080008000800080008000800080008 00055 4d 8d 5a 08 lea r11, QWORD PTR [r10+8] 00059 48 89 6c 24 20 mov QWORD PTR [rsp+32], rbp 0005e ff c8 dec eax 00060 4c 89 74 24 28 mov QWORD PTR [rsp+40], r14 00065 0f 57 e4 xorps xmm4, xmm4 00068 c1 e8 03 shr eax, 3 0006b 4c 8b f7 mov r14, rdi 0006e ff c0 inc eax 00070 4c 89 7c 24 30 mov QWORD PTR [rsp+48], r15 00075 49 8b ea mov rbp, r10 00078 44 8b f8 mov r15d, eax 0007b 44 8d 0c c5 00 00 00 00 lea r9d, DWORD PTR [rax*8] 00083 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL4@stbi__resa: ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); 00090 42 0f b6 04 1b movzx eax, BYTE PTR [rbx+r11] 00095 4d 8d 76 10 lea r14, QWORD PTR [r14+16] 00099 f3 0f 7e 04 2b movq xmm0, QWORD PTR [rbx+rbp] 0009e 4d 8d 5b 08 lea r11, QWORD PTR [r11+8] 000a2 f3 0f 7e 5d 00 movq xmm3, QWORD PTR [rbp] 000a7 48 8d 6d 08 lea rbp, QWORD PTR [rbp+8] 000ab 66 0f 60 c4 punpcklbw xmm0, xmm4 000af 8d 0c 40 lea ecx, DWORD PTR [rax+rax*2] 000b2 66 0f 60 dc punpcklbw xmm3, xmm4 000b6 41 0f b6 43 f8 movzx eax, BYTE PTR [r11-8] 000bb 66 0f f9 d8 psubw xmm3, xmm0 000bf 66 0f 71 f0 02 psllw xmm0, 2 000c4 03 c8 add ecx, eax 000c6 66 0f fd d8 paddw xmm3, xmm0 000ca 66 0f 6f d3 movdqa xmm2, xmm3 000ce 66 0f 6f cb movdqa xmm1, xmm3 000d2 66 0f 73 fa 02 pslldq xmm2, 2 ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); 000d7 66 0f 6f c3 movdqa xmm0, xmm3 000db 66 41 0f c4 d0 00 pinsrw xmm2, r8d, 0 000e1 66 0f 71 f0 02 psllw xmm0, 2 ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); 000e6 66 0f f9 d3 psubw xmm2, xmm3 ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); 000ea 66 0f fd c5 paddw xmm0, xmm5 000ee 66 0f 73 d9 02 psrldq xmm1, 2 ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); 000f3 66 0f fd d0 paddw xmm2, xmm0 000f7 66 0f c4 c9 07 pinsrw xmm1, ecx, 7 000fc 66 0f f9 cb psubw xmm1, xmm3 ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); 00100 66 0f fd c8 paddw xmm1, xmm0 ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); 00104 66 0f 6f c2 movdqa xmm0, xmm2 00108 66 0f 61 c1 punpcklwd xmm0, xmm1 ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); 0010c 66 0f 69 d1 punpckhwd xmm2, xmm1 ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); 00110 66 0f 71 d0 04 psrlw xmm0, 4 ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); 00115 66 0f 71 d2 04 psrlw xmm2, 4 ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); 0011a 66 0f 67 c2 packuswb xmm0, xmm2 ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); 0011e f3 41 0f 7f 46 f0 movdqu XMMWORD PTR [r14-16], xmm0 ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; 00124 42 0f b6 44 1b f7 movzx eax, BYTE PTR [rbx+r11-9] 0012a 44 8d 04 40 lea r8d, DWORD PTR [rax+rax*2] 0012e 41 0f b6 43 f7 movzx eax, BYTE PTR [r11-9] 00133 44 03 c0 add r8d, eax 00136 49 83 ef 01 sub r15, 1 0013a 0f 85 50 ff ff ff jne $LL4@stbi__resa 00140 4c 8b 7c 24 30 mov r15, QWORD PTR [rsp+48] 00145 4c 8b 74 24 28 mov r14, QWORD PTR [rsp+40] 0014a 48 8b 6c 24 20 mov rbp, QWORD PTR [rsp+32] $LN18@stbi__resa: ; 3111 : t1 = 3 * in_near[i] + in_far[i]; 0014f 49 63 c9 movsxd rcx, r9d ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { 00152 4c 8b de mov r11, rsi 00155 0f b6 04 11 movzx eax, BYTE PTR [rcx+rdx] 00159 42 0f b6 0c 11 movzx ecx, BYTE PTR [rcx+r10] 0015e 8d 04 40 lea eax, DWORD PTR [rax+rax*2] 00161 03 c1 add eax, ecx 00163 43 8d 0c 09 lea ecx, DWORD PTR [r9+r9] 00167 48 63 d1 movsxd rdx, ecx 0016a 41 8d 49 01 lea ecx, DWORD PTR [r9+1] 0016e 45 8d 04 40 lea r8d, DWORD PTR [r8+rax*2] 00172 41 83 c0 08 add r8d, 8 00176 44 03 c0 add r8d, eax 00179 41 c1 e8 04 shr r8d, 4 0017d 44 88 04 3a mov BYTE PTR [rdx+rdi], r8b 00181 48 63 d1 movsxd rdx, ecx 00184 48 3b d6 cmp rdx, rsi 00187 7d 57 jge SHORT $LN6@stbi__resa ; 3108 : } ; 3109 : ; 3110 : t0 = t1; 00189 4e 8d 0c 12 lea r9, QWORD PTR [rdx+r10] 0018d 4c 2b da sub r11, rdx 00190 4c 8d 14 57 lea r10, QWORD PTR [rdi+rdx*2] 00194 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL7@stbi__resa: ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; 001a0 41 0f b6 09 movzx ecx, BYTE PTR [r9] 001a4 4d 8d 52 02 lea r10, QWORD PTR [r10+2] 001a8 44 8b c0 mov r8d, eax 001ab 42 0f b6 04 0b movzx eax, BYTE PTR [rbx+r9] 001b0 4d 8d 49 01 lea r9, QWORD PTR [r9+1] 001b4 8d 04 40 lea eax, DWORD PTR [rax+rax*2] 001b7 03 c1 add eax, ecx ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); 001b9 41 8d 50 04 lea edx, DWORD PTR [r8+4] 001bd 8d 14 50 lea edx, DWORD PTR [rax+rdx*2] 001c0 41 03 d0 add edx, r8d 001c3 c1 ea 04 shr edx, 4 001c6 41 88 52 fd mov BYTE PTR [r10-3], dl ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); 001ca 8d 50 04 lea edx, DWORD PTR [rax+4] 001cd 41 8d 14 50 lea edx, DWORD PTR [r8+rdx*2] 001d1 03 d0 add edx, eax 001d3 c1 ea 04 shr edx, 4 001d6 41 88 52 fe mov BYTE PTR [r10-2], dl 001da 49 83 eb 01 sub r11, 1 001de 75 c0 jne SHORT $LL7@stbi__resa $LN6@stbi__resa: ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; 001e0 48 8b 5c 24 18 mov rbx, QWORD PTR [rsp+24] 001e5 8d 50 02 lea edx, DWORD PTR [rax+2] 001e8 8d 04 36 lea eax, DWORD PTR [rsi+rsi] 001eb c1 ea 02 shr edx, 2 001ee 48 63 c8 movsxd rcx, eax ; 3125 : } 001f1 48 8b c7 mov rax, rdi 001f4 88 54 39 ff mov BYTE PTR [rcx+rdi-1], dl 001f8 5f pop rdi 001f9 5e pop rsi 001fa c3 ret 0 stbi__resample_row_hv_2_simd ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__resample_row_generic _TEXT SEGMENT out$ = 8 in_near$ = 16 in_far$ = 24 w$ = 32 hs$ = 40 stbi__resample_row_generic PROC ; COMDAT ; 3129 : { 00000 4c 8b d9 mov r11, rcx ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) 00003 45 85 c9 test r9d, r9d 00006 7e 33 jle SHORT $LN17@stbi__resa 00008 4c 63 44 24 28 movsxd r8, DWORD PTR hs$[rsp] 0000d 4c 8b d1 mov r10, rcx 00010 45 8b c9 mov r9d, r9d $LL4@stbi__resa: ; 3134 : for (j = 0; j < hs; ++j) 00013 4d 85 c0 test r8, r8 00016 7e 17 jle SHORT $LN2@stbi__resa ; 3135 : out[i * hs + j] = in_near[i]; 00018 33 c0 xor eax, eax 0001a 66 0f 1f 44 00 00 npad 6 $LL7@stbi__resa: 00020 0f b6 0a movzx ecx, BYTE PTR [rdx] 00023 41 88 0c 02 mov BYTE PTR [r10+rax], cl 00027 48 ff c0 inc rax 0002a 49 3b c0 cmp rax, r8 0002d 7c f1 jl SHORT $LL7@stbi__resa $LN2@stbi__resa: ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) 0002f 4d 03 d0 add r10, r8 00032 48 ff c2 inc rdx 00035 49 83 e9 01 sub r9, 1 00039 75 d8 jne SHORT $LL4@stbi__resa $LN17@stbi__resa: ; 3136 : return out; ; 3137 : } 0003b 49 8b c3 mov rax, r11 0003e c3 ret 0 stbi__resample_row_generic ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__YCbCr_to_RGB_row _TEXT SEGMENT out$ = 24 y$ = 32 pcb$ = 40 pcr$ = 48 count$ = 56 step$ = 64 stbi__YCbCr_to_RGB_row PROC ; COMDAT ; 3143 : { 00000 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx 00005 48 89 6c 24 20 mov QWORD PTR [rsp+32], rbp 0000a 57 push rdi 0000b 41 56 push r14 ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { 0000d 48 63 7c 24 38 movsxd rdi, DWORD PTR count$[rsp] 00012 49 8b d9 mov rbx, r9 00015 49 8b e8 mov rbp, r8 00018 4c 8b f2 mov r14, rdx 0001b 48 85 ff test rdi, rdi 0001e 0f 8e f2 00 00 00 jle $LN3@stbi__YCbC 00024 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 00029 48 8d 41 02 lea rax, QWORD PTR [rcx+2] 0002d 48 63 74 24 40 movsxd rsi, DWORD PTR step$[rsp] 00032 4c 2b f3 sub r14, rbx ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding 00035 48 2b eb sub rbp, rbx 00038 4c 89 7c 24 20 mov QWORD PTR [rsp+32], r15 0003d 45 33 ff xor r15d, r15d $LL4@stbi__YCbC: ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; 00040 44 0f b6 03 movzx r8d, BYTE PTR [rbx] ; 3149 : int cb = pcb[i] - 128; 00044 44 0f b6 0c 2b movzx r9d, BYTE PTR [rbx+rbp] 00049 45 0f b6 14 1e movzx r10d, BYTE PTR [r14+rbx] 0004e 41 c1 e2 14 shl r10d, 20 ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); 00052 41 8d 48 80 lea ecx, DWORD PTR [r8-128] 00056 41 81 c2 00 00 08 00 add r10d, 524288 ; 00080000H 0005d 44 69 d9 00 6f 16 00 imul r11d, ecx, 1470208 ; 00166f00H ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); 00064 b9 80 00 00 00 mov ecx, 128 ; 00000080H 00069 41 2b c9 sub ecx, r9d 0006c 69 d1 00 82 05 00 imul edx, ecx, 360960 ; 00058200H 00072 b9 80 00 00 00 mov ecx, 128 ; 00000080H 00077 41 2b c8 sub ecx, r8d 0007a 44 69 c1 00 6d 0b 00 imul r8d, ecx, 748800 ; 000b6d00H 00081 45 03 da add r11d, r10d ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; 00084 41 c1 fb 14 sar r11d, 20 00088 81 e2 00 00 ff ff and edx, -65536 ; ffffffffffff0000H 0008e 41 8d 0c 12 lea ecx, DWORD PTR [r10+rdx] 00092 44 03 c1 add r8d, ecx 00095 41 8d 49 80 lea ecx, DWORD PTR [r9-128] 00099 69 d1 00 5a 1c 00 imul edx, ecx, 1858048 ; 001c5a00H ; 3154 : g >>= 20; 0009f 41 c1 f8 14 sar r8d, 20 000a3 41 03 d2 add edx, r10d ; 3155 : b >>= 20; 000a6 c1 fa 14 sar edx, 20 ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } 000a9 41 81 fb ff 00 00 00 cmp r11d, 255 ; 000000ffH 000b0 76 0f jbe SHORT $LN6@stbi__YCbC 000b2 45 85 db test r11d, r11d 000b5 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 000ba 41 0f 48 cf cmovs ecx, r15d 000be 44 8b d9 mov r11d, ecx $LN6@stbi__YCbC: ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } 000c1 41 81 f8 ff 00 00 00 cmp r8d, 255 ; 000000ffH 000c8 76 0f jbe SHORT $LN9@stbi__YCbC 000ca 45 85 c0 test r8d, r8d 000cd b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 000d2 41 0f 48 cf cmovs ecx, r15d 000d6 44 8b c1 mov r8d, ecx $LN9@stbi__YCbC: ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } 000d9 81 fa ff 00 00 00 cmp edx, 255 ; 000000ffH 000df 76 0d jbe SHORT $LN12@stbi__YCbC 000e1 85 d2 test edx, edx 000e3 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 000e8 41 0f 48 cf cmovs ecx, r15d 000ec 8b d1 mov edx, ecx $LN12@stbi__YCbC: ; 3159 : out[0] = (stbi_uc)r; 000ee 44 88 58 fe mov BYTE PTR [rax-2], r11b 000f2 48 ff c3 inc rbx ; 3160 : out[1] = (stbi_uc)g; 000f5 44 88 40 ff mov BYTE PTR [rax-1], r8b ; 3161 : out[2] = (stbi_uc)b; 000f9 88 10 mov BYTE PTR [rax], dl ; 3162 : out[3] = 255; 000fb c6 40 01 ff mov BYTE PTR [rax+1], 255 ; 000000ffH ; 3163 : out += step; 000ff 48 03 c6 add rax, rsi 00102 48 83 ef 01 sub rdi, 1 00106 0f 85 34 ff ff ff jne $LL4@stbi__YCbC ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { 0010c 4c 8b 7c 24 20 mov r15, QWORD PTR [rsp+32] 00111 48 8b 74 24 18 mov rsi, QWORD PTR [rsp+24] $LN3@stbi__YCbC: ; 3164 : } ; 3165 : } 00116 48 8b 5c 24 28 mov rbx, QWORD PTR [rsp+40] 0011b 48 8b 6c 24 30 mov rbp, QWORD PTR [rsp+48] 00120 41 5e pop r14 00122 5f pop rdi 00123 c3 ret 0 stbi__YCbCr_to_RGB_row ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__YCbCr_to_RGB_simd _TEXT SEGMENT out$ = 128 y$ = 136 pcb$ = 144 pcr$ = 152 count$ = 160 step$ = 168 stbi__YCbCr_to_RGB_simd PROC ; COMDAT ; 3169 : { 00000 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 00005 56 push rsi 00006 57 push rdi 00007 41 57 push r15 00009 48 83 ec 60 sub rsp, 96 ; 00000060H ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { 0000d 4c 63 94 24 a8 00 00 00 movsxd r10, DWORD PTR step$[rsp] 00015 45 33 ff xor r15d, r15d 00018 49 8b f0 mov rsi, r8 0001b 48 8b ea mov rbp, rdx 0001e 48 63 94 24 a0 00 00 00 movsxd rdx, DWORD PTR count$[rsp] 00026 45 8b c7 mov r8d, r15d 00029 41 83 fa 04 cmp r10d, 4 0002d 0f 85 3c 01 00 00 jne $LN3@stbi__YCbC ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); 00033 66 0f 6f 2d 00 00 00 00 movdqa xmm5, XMMWORD PTR __xmm@80808080808080808080808080808080 0003b 0f 29 7c 24 40 movaps XMMWORD PTR [rsp+64], xmm7 ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); 00040 66 0f 6f 3d 00 00 00 00 movdqa xmm7, XMMWORD PTR __xmm@166f166f166f166f166f166f166f166f 00048 44 0f 29 44 24 30 movaps XMMWORD PTR [rsp+48], xmm8 ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); 0004e 66 44 0f 6f 05 00 00 00 00 movdqa xmm8, XMMWORD PTR __xmm@f493f493f493f493f493f493f493f493 00057 44 0f 29 4c 24 20 movaps XMMWORD PTR [rsp+32], xmm9 ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); 0005d 66 44 0f 6f 0d 00 00 00 00 movdqa xmm9, XMMWORD PTR __xmm@fa7efa7efa7efa7efa7efa7efa7efa7e 00066 44 0f 29 54 24 10 movaps XMMWORD PTR [rsp+16], xmm10 ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); 0006c 66 44 0f 6f 15 00 00 00 00 movdqa xmm10, XMMWORD PTR __xmm@1c5a1c5a1c5a1c5a1c5a1c5a1c5a1c5a 00075 44 0f 29 1c 24 movaps XMMWORD PTR [rsp], xmm11 ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel 0007a 66 44 0f 6f 1d 00 00 00 00 movdqa xmm11, XMMWORD PTR __xmm@00ff00ff00ff00ff00ff00ff00ff00ff ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { 00083 83 fa 07 cmp edx, 7 00086 0f 8e c7 00 00 00 jle $LN37@stbi__YCbC 0008c 0f 29 74 24 50 movaps XMMWORD PTR [rsp+80], xmm6 00091 0f 57 f6 xorps xmm6, xmm6 00094 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__YCbC: ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); 000a0 49 63 c0 movsxd rax, r8d ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); 000a3 66 0f 6f d6 movdqa xmm2, xmm6 000a7 41 83 c0 08 add r8d, 8 ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); 000ab 66 0f 6f e6 movdqa xmm4, xmm6 000af 66 0f 6f cd movdqa xmm1, xmm5 000b3 f3 42 0f 7e 04 08 movq xmm0, QWORD PTR [rax+r9] 000b9 0f 57 c5 xorps xmm0, xmm5 000bc 66 0f 60 d0 punpcklbw xmm2, xmm0 000c0 f3 0f 7e 04 30 movq xmm0, QWORD PTR [rax+rsi] ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); 000c5 66 0f 6f da movdqa xmm3, xmm2 000c9 0f 57 c5 xorps xmm0, xmm5 000cc 66 0f e5 df pmulhw xmm3, xmm7 000d0 66 0f 60 e0 punpcklbw xmm4, xmm0 000d4 f3 0f 7e 04 28 movq xmm0, QWORD PTR [rax+rbp] 000d9 41 8d 40 07 lea eax, DWORD PTR [r8+7] 000dd 66 0f 60 c8 punpcklbw xmm1, xmm0 ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); 000e1 66 0f 6f c4 movdqa xmm0, xmm4 000e5 66 0f 71 d1 04 psrlw xmm1, 4 ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); 000ea 66 0f fd d9 paddw xmm3, xmm1 000ee 66 41 0f e5 c2 pmulhw xmm0, xmm10 000f3 66 41 0f e5 e1 pmulhw xmm4, xmm9 ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); 000f8 66 0f 71 e3 04 psraw xmm3, 4 000fd 66 41 0f e5 d0 pmulhw xmm2, xmm8 00102 66 0f fd c1 paddw xmm0, xmm1 00106 66 0f fd e1 paddw xmm4, xmm1 ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); 0010a 66 0f 71 e0 04 psraw xmm0, 4 ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); 0010f 66 0f 67 d8 packuswb xmm3, xmm0 00113 66 0f fd e2 paddw xmm4, xmm2 ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); 00117 66 0f 6f cb movdqa xmm1, xmm3 0011b 66 0f 71 e4 04 psraw xmm4, 4 00120 66 41 0f 67 e3 packuswb xmm4, xmm11 00125 66 0f 60 cc punpcklbw xmm1, xmm4 ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); 00129 66 0f 6f c1 movdqa xmm0, xmm1 0012d 66 0f 68 dc punpckhbw xmm3, xmm4 00131 66 0f 61 c3 punpcklwd xmm0, xmm3 ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); 00135 66 0f 69 cb punpckhwd xmm1, xmm3 ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); 00139 f3 0f 7f 01 movdqu XMMWORD PTR [rcx], xmm0 ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); 0013d f3 0f 7f 49 10 movdqu XMMWORD PTR [rcx+16], xmm1 ; 3228 : out += 32; 00142 48 83 c1 20 add rcx, 32 ; 00000020H 00146 3b c2 cmp eax, edx 00148 0f 8c 52 ff ff ff jl $LL4@stbi__YCbC ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { 0014e 0f 28 74 24 50 movaps xmm6, XMMWORD PTR [rsp+80] $LN37@stbi__YCbC: 00153 44 0f 28 54 24 10 movaps xmm10, XMMWORD PTR [rsp+16] 00159 44 0f 28 4c 24 20 movaps xmm9, XMMWORD PTR [rsp+32] 0015f 44 0f 28 44 24 30 movaps xmm8, XMMWORD PTR [rsp+48] 00165 0f 28 7c 24 40 movaps xmm7, XMMWORD PTR [rsp+64] 0016a 44 0f 28 1c 24 movaps xmm11, XMMWORD PTR [rsp] $LN3@stbi__YCbC: ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { 0016f 49 63 c0 movsxd rax, r8d 00172 48 8b fa mov rdi, rdx 00175 48 3b c2 cmp rax, rdx 00178 0f 8d f8 00 00 00 jge $LN6@stbi__YCbC 0017e 48 89 9c 24 80 00 00 00 mov QWORD PTR [rsp+128], rbx 00186 4c 8d 59 02 lea r11, QWORD PTR [rcx+2] 0018a 49 2b e9 sub rbp, r9 0018d 4c 89 b4 24 88 00 00 00 mov QWORD PTR [rsp+136], r14 00195 49 2b f1 sub rsi, r9 00198 4a 8d 1c 08 lea rbx, QWORD PTR [rax+r9] 0019c 4d 8b f2 mov r14, r10 0019f 48 2b f8 sub rdi, rax $LL7@stbi__YCbC: ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; 001a2 0f b6 13 movzx edx, BYTE PTR [rbx] ; 3283 : int cb = pcb[i] - 128; 001a5 44 0f b6 04 33 movzx r8d, BYTE PTR [rbx+rsi] 001aa 44 0f b6 0c 2b movzx r9d, BYTE PTR [rbx+rbp] 001af 41 c1 e1 14 shl r9d, 20 ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); 001b3 8d 42 80 lea eax, DWORD PTR [rdx-128] 001b6 41 81 c1 00 00 08 00 add r9d, 524288 ; 00080000H 001bd 44 69 d0 00 6f 16 00 imul r10d, eax, 1470208 ; 00166f00H ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); 001c4 b8 80 00 00 00 mov eax, 128 ; 00000080H 001c9 41 2b c0 sub eax, r8d 001cc 69 c8 00 82 05 00 imul ecx, eax, 360960 ; 00058200H 001d2 b8 80 00 00 00 mov eax, 128 ; 00000080H 001d7 2b c2 sub eax, edx 001d9 69 d0 00 6d 0b 00 imul edx, eax, 748800 ; 000b6d00H 001df 45 03 d1 add r10d, r9d ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; 001e2 41 c1 fa 14 sar r10d, 20 001e6 81 e1 00 00 ff ff and ecx, -65536 ; ffffffffffff0000H 001ec 41 8d 04 09 lea eax, DWORD PTR [r9+rcx] 001f0 03 d0 add edx, eax 001f2 41 8d 40 80 lea eax, DWORD PTR [r8-128] 001f6 69 c0 00 5a 1c 00 imul eax, eax, 1858048 ; 001c5a00H ; 3288 : g >>= 20; 001fc c1 fa 14 sar edx, 20 001ff 41 03 c1 add eax, r9d ; 3289 : b >>= 20; 00202 c1 f8 14 sar eax, 20 ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } 00205 41 81 fa ff 00 00 00 cmp r10d, 255 ; 000000ffH 0020c 76 0f jbe SHORT $LN10@stbi__YCbC 0020e 45 85 d2 test r10d, r10d 00211 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 00216 41 0f 48 cf cmovs ecx, r15d 0021a 44 8b d1 mov r10d, ecx $LN10@stbi__YCbC: ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } 0021d 81 fa ff 00 00 00 cmp edx, 255 ; 000000ffH 00223 76 0d jbe SHORT $LN13@stbi__YCbC 00225 85 d2 test edx, edx 00227 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 0022c 41 0f 48 cf cmovs ecx, r15d 00230 8b d1 mov edx, ecx $LN13@stbi__YCbC: ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } 00232 3d ff 00 00 00 cmp eax, 255 ; 000000ffH 00237 76 0d jbe SHORT $LN16@stbi__YCbC 00239 85 c0 test eax, eax 0023b b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 00240 41 0f 48 cf cmovs ecx, r15d 00244 8b c1 mov eax, ecx $LN16@stbi__YCbC: ; 3293 : out[0] = (stbi_uc)r; 00246 45 88 53 fe mov BYTE PTR [r11-2], r10b 0024a 48 ff c3 inc rbx ; 3294 : out[1] = (stbi_uc)g; 0024d 41 88 53 ff mov BYTE PTR [r11-1], dl ; 3295 : out[2] = (stbi_uc)b; 00251 41 88 03 mov BYTE PTR [r11], al ; 3296 : out[3] = 255; 00254 41 c6 43 01 ff mov BYTE PTR [r11+1], 255 ; 000000ffH ; 3297 : out += step; 00259 4d 03 de add r11, r14 0025c 48 83 ef 01 sub rdi, 1 00260 0f 85 3c ff ff ff jne $LL7@stbi__YCbC ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { 00266 4c 8b b4 24 88 00 00 00 mov r14, QWORD PTR [rsp+136] 0026e 48 8b 9c 24 80 00 00 00 mov rbx, QWORD PTR [rsp+128] $LN6@stbi__YCbC: ; 3298 : } ; 3299 : } 00276 48 8b ac 24 90 00 00 00 mov rbp, QWORD PTR [rsp+144] 0027e 48 83 c4 60 add rsp, 96 ; 00000060H 00282 41 5f pop r15 00284 5f pop rdi 00285 5e pop rsi 00286 c3 ret 0 stbi__YCbCr_to_RGB_simd ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__setup_jpeg _TEXT SEGMENT j$ = 32 stbi__setup_jpeg PROC ; COMDAT ; 3304 : { 00000 40 53 push rbx 00002 48 83 ec 10 sub rsp, 16 ; 3305 : j->idct_block_kernel = stbi__idct_block; 00006 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_block 0000d 4c 8b c1 mov r8, rcx 00010 48 89 81 70 48 00 00 mov QWORD PTR [rcx+18544], rax ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; 00017 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_row 0001e 48 89 81 78 48 00 00 mov QWORD PTR [rcx+18552], rax ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; 00025 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2 0002c 48 89 81 80 48 00 00 mov QWORD PTR [rcx+18560], rax ; 187 : __cpuid(info, 1); 00033 33 c9 xor ecx, ecx 00035 b8 01 00 00 00 mov eax, 1 0003a 0f a2 cpuid ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { 0003c 0f ba e2 1a bt edx, 26 00040 73 2a jae SHORT $LN2@stbi__setu ; 3311 : j->idct_block_kernel = stbi__idct_simd; 00042 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_simd 00049 49 89 80 70 48 00 00 mov QWORD PTR [r8+18544], rax ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; 00050 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_simd 00057 49 89 80 78 48 00 00 mov QWORD PTR [r8+18552], rax ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; 0005e 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2_simd 00065 49 89 80 80 48 00 00 mov QWORD PTR [r8+18560], rax $LN2@stbi__setu: ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } 0006c 48 83 c4 10 add rsp, 16 00070 5b pop rbx 00071 c3 ret 0 stbi__setup_jpeg ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__cleanup_jpeg _TEXT SEGMENT j$ = 8 stbi__cleanup_jpeg PROC ; COMDAT ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); 00000 48 8b 11 mov rdx, QWORD PTR [rcx] 00003 45 33 c0 xor r8d, r8d 00006 8b 52 08 mov edx, DWORD PTR [rdx+8] 00009 e9 00 00 00 00 jmp stbi__free_jpeg_components stbi__cleanup_jpeg ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__blinn_8x8 _TEXT SEGMENT x$ = 8 y$ = 16 stbi__blinn_8x8 PROC ; COMDAT ; 3343 : unsigned int t = x * y + 128; 00000 0f b6 c2 movzx eax, dl 00003 44 0f b6 c1 movzx r8d, cl 00007 44 0f af c0 imul r8d, eax 0000b 41 83 e8 80 sub r8d, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 0000f 41 8b c0 mov eax, r8d 00012 c1 e8 08 shr eax, 8 00015 41 03 c0 add eax, r8d 00018 c1 e8 08 shr eax, 8 ; 3345 : } 0001b c3 ret 0 stbi__blinn_8x8 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT load_jpeg_image _TEXT SEGMENT j$1$ = 48 output$2$ = 56 tv3179 = 64 tv3132 = 72 coutput$4 = 80 out$1$ = 112 z$GSCopy$1$ = 120 out_x$GSCopy$1$ = 128 out_y$GSCopy$1$ = 136 comp$GSCopy$1$ = 144 res_comp$5 = 160 __$ArrayPad$ = 352 z$ = 448 out_x$ = 456 out_y$ = 464 comp$ = 472 req_comp$ = 480 load_jpeg_image PROC ; COMDAT ; 3348 : { 00000 40 56 push rsi 00002 41 55 push r13 00004 41 57 push r15 00006 48 81 ec a0 01 00 00 sub rsp, 416 ; 000001a0H 0000d 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00014 48 33 c4 xor rax, rsp 00017 48 89 84 24 60 01 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe 0001f 48 8b 01 mov rax, QWORD PTR [rcx] 00022 45 33 ed xor r13d, r13d ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); 00025 44 8b bc 24 e0 01 00 00 mov r15d, DWORD PTR req_comp$[rsp] 0002d 48 8b f1 mov rsi, rcx 00030 4c 89 8c 24 90 00 00 00 mov QWORD PTR comp$GSCopy$1$[rsp], r9 00038 4c 89 84 24 88 00 00 00 mov QWORD PTR out_y$GSCopy$1$[rsp], r8 00040 44 89 68 08 mov DWORD PTR [rax+8], r13d 00044 48 89 94 24 80 00 00 00 mov QWORD PTR out_x$GSCopy$1$[rsp], rdx 0004c 48 89 4c 24 78 mov QWORD PTR z$GSCopy$1$[rsp], rcx 00051 41 83 ff 04 cmp r15d, 4 00055 0f 87 45 08 00 00 ja $LN42@load_jpeg_ ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } 0005b e8 00 00 00 00 call stbi__decode_jpeg_image 00060 85 c0 test eax, eax 00062 75 18 jne SHORT $LN43@load_jpeg_ ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); 00064 48 8b 16 mov rdx, QWORD PTR [rsi] 00067 45 33 c0 xor r8d, r8d 0006a 48 8b ce mov rcx, rsi 0006d 8b 52 08 mov edx, DWORD PTR [rdx+8] 00070 e8 00 00 00 00 call stbi__free_jpeg_components ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } 00075 33 c0 xor eax, eax 00077 e9 cf 07 00 00 jmp $LN1@load_jpeg_ $LN43@load_jpeg_: 0007c 4c 89 a4 24 80 01 00 00 mov QWORD PTR [rsp+384], r12 ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; 00084 b9 03 00 00 00 mov ecx, 3 00089 44 8d 61 fe lea r12d, QWORD PTR [rcx-2] 0008d 45 85 ff test r15d, r15d 00090 75 15 jne SHORT $LN84@load_jpeg_ 00092 48 8b 06 mov rax, QWORD PTR [rsi] 00095 45 8b fc mov r15d, r12d 00098 39 48 08 cmp DWORD PTR [rax+8], ecx 0009b 44 0f 4d f9 cmovge r15d, ecx 0009f 44 89 bc 24 e0 01 00 00 mov DWORD PTR req_comp$[rsp], r15d $LN84@load_jpeg_: ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); 000a7 48 8b 06 mov rax, QWORD PTR [rsi] 000aa 8b 48 08 mov ecx, DWORD PTR [rax+8] 000ad 83 f9 03 cmp ecx, 3 000b0 75 24 jne SHORT $LN87@load_jpeg_ 000b2 39 8e 50 48 00 00 cmp DWORD PTR [rsi+18512], ecx 000b8 74 12 je SHORT $LN86@load_jpeg_ 000ba 44 39 ae 4c 48 00 00 cmp DWORD PTR [rsi+18508], r13d 000c1 75 13 jne SHORT $LN87@load_jpeg_ 000c3 44 39 ae 48 48 00 00 cmp DWORD PTR [rsi+18504], r13d 000ca 75 0a jne SHORT $LN87@load_jpeg_ $LN86@load_jpeg_: 000cc 41 8b c4 mov eax, r12d 000cf 4c 89 64 24 40 mov QWORD PTR tv3179[rsp], r12 000d4 eb 11 jmp SHORT $LN236@load_jpeg_ $LN87@load_jpeg_: ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) 000d6 4c 89 6c 24 40 mov QWORD PTR tv3179[rsp], r13 000db 41 8b c5 mov eax, r13d 000de 83 f9 03 cmp ecx, 3 000e1 0f 85 de 00 00 00 jne $LN44@load_jpeg_ $LN236@load_jpeg_: 000e7 41 83 ff 03 cmp r15d, 3 000eb 0f 8d d4 00 00 00 jge $LN44@load_jpeg_ 000f1 85 c0 test eax, eax 000f3 0f 85 cc 00 00 00 jne $LN44@load_jpeg_ ; 3364 : decode_n = 1; 000f9 41 8b cc mov ecx, r12d $LN46@load_jpeg_: 000fc 48 89 9c 24 98 01 00 00 mov QWORD PTR [rsp+408], rbx 00104 0f 57 c0 xorps xmm0, xmm0 00107 48 89 ac 24 90 01 00 00 mov QWORD PTR [rsp+400], rbp 0010f 0f 57 c9 xorps xmm1, xmm1 00112 48 89 bc 24 88 01 00 00 mov QWORD PTR [rsp+392], rdi 0011a 4c 89 b4 24 78 01 00 00 mov QWORD PTR [rsp+376], r14 ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { 00122 44 8b f1 mov r14d, ecx 00125 4c 89 74 24 48 mov QWORD PTR tv3132[rsp], r14 0012a f3 0f 7f 44 24 50 movdqu XMMWORD PTR coutput$4[rsp], xmm0 00130 f3 0f 7f 4c 24 60 movdqu XMMWORD PTR coutput$4[rsp+16], xmm1 00136 85 c9 test ecx, ecx 00138 0f 84 f4 00 00 00 je $LN3@load_jpeg_ 0013e 49 8b ed mov rbp, r13 00141 48 8d 9c 24 bc 00 00 00 lea rbx, QWORD PTR res_comp$5[rsp+28] 00149 48 8d be a4 46 00 00 lea rdi, QWORD PTR [rsi+18084] $LL4@load_jpeg_: ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); 00150 48 8b 06 mov rax, QWORD PTR [rsi] 00153 8b 08 mov ecx, DWORD PTR [rax] 00155 83 c1 03 add ecx, 3 ; 438 : return STBI_MALLOC(size); 00158 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); 0015e 48 89 47 44 mov QWORD PTR [rdi+68], rax ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } 00162 48 85 c0 test rax, rax 00165 0f 84 fd 06 00 00 je $LN241@load_jpeg_ ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; 0016b 8b 86 88 46 00 00 mov eax, DWORD PTR [rsi+18056] 00171 99 cdq ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; 00172 44 89 6b 0c mov DWORD PTR [rbx+12], r13d 00176 f7 3f idiv DWORD PTR [rdi] 00178 44 8b c8 mov r9d, eax 0017b 89 43 fc mov DWORD PTR [rbx-4], eax 0017e 8b 86 8c 46 00 00 mov eax, DWORD PTR [rsi+18060] 00184 99 cdq 00185 f7 7f 04 idiv DWORD PTR [rdi+4] 00188 33 d2 xor edx, edx 0018a 8b c8 mov ecx, eax 0018c 89 03 mov DWORD PTR [rbx], eax 0018e d1 f9 sar ecx, 1 00190 44 8b c0 mov r8d, eax 00193 89 4b 08 mov DWORD PTR [rbx+8], ecx 00196 48 8b 0e mov rcx, QWORD PTR [rsi] 00199 8b 01 mov eax, DWORD PTR [rcx] ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; 0019b 48 8b 4f 2c mov rcx, QWORD PTR [rdi+44] 0019f ff c8 dec eax 001a1 41 03 c1 add eax, r9d 001a4 48 89 4b f4 mov QWORD PTR [rbx-12], rcx 001a8 41 f7 f1 div r9d 001ab 48 89 4b ec mov QWORD PTR [rbx-20], rcx 001af 89 43 04 mov DWORD PTR [rbx+4], eax ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; 001b2 45 3b cc cmp r9d, r12d 001b5 75 39 jne SHORT $LN218@load_jpeg_ 001b7 45 3b c4 cmp r8d, r12d 001ba 75 25 jne SHORT $LN217@load_jpeg_ 001bc 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:resample_row_1 001c3 eb 55 jmp SHORT $LN2@load_jpeg_ $LN44@load_jpeg_: ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } 001c5 85 c9 test ecx, ecx 001c7 0f 8f 2f ff ff ff jg $LN46@load_jpeg_ ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); 001cd 8b d1 mov edx, ecx 001cf 45 33 c0 xor r8d, r8d 001d2 48 8b ce mov rcx, rsi 001d5 e8 00 00 00 00 call stbi__free_jpeg_components ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } 001da 33 c0 xor eax, eax 001dc e9 62 06 00 00 jmp $LN301@load_jpeg_ $LN217@load_jpeg_: ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; 001e1 41 83 f8 02 cmp r8d, 2 001e5 75 2c jne SHORT $LN54@load_jpeg_ 001e7 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_v_2 001ee eb 2a jmp SHORT $LN2@load_jpeg_ $LN218@load_jpeg_: ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; 001f0 41 83 f9 02 cmp r9d, 2 001f4 75 1d jne SHORT $LN54@load_jpeg_ 001f6 45 3b c4 cmp r8d, r12d 001f9 75 09 jne SHORT $LN219@load_jpeg_ 001fb 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_h_2 00202 eb 16 jmp SHORT $LN2@load_jpeg_ $LN219@load_jpeg_: ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; 00204 41 83 f8 02 cmp r8d, 2 00208 75 09 jne SHORT $LN54@load_jpeg_ 0020a 48 8b 86 80 48 00 00 mov rax, QWORD PTR [rsi+18560] 00211 eb 07 jmp SHORT $LN2@load_jpeg_ $LN54@load_jpeg_: ; 3400 : else r->resample = stbi__resample_row_generic; 00213 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_generic $LN2@load_jpeg_: ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { 0021a 48 89 43 e4 mov QWORD PTR [rbx-28], rax 0021e 48 ff c5 inc rbp 00221 48 83 c3 30 add rbx, 48 ; 00000030H 00225 48 83 c7 60 add rdi, 96 ; 00000060H 00229 49 3b ee cmp rbp, r14 0022c 0f 8c 1e ff ff ff jl $LL4@load_jpeg_ $LN3@load_jpeg_: ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); 00232 48 8b 06 mov rax, QWORD PTR [rsi] 00235 44 8b 40 04 mov r8d, DWORD PTR [rax+4] 00239 8b 08 mov ecx, DWORD PTR [rax] ; 467 : if (a < 0 || b < 0) return 0; 0023b 45 85 ff test r15d, r15d 0023e 0f 88 24 06 00 00 js $LN241@load_jpeg_ 00244 85 c9 test ecx, ecx 00246 0f 88 1c 06 00 00 js $LN241@load_jpeg_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0024c 74 11 je SHORT $LN243@load_jpeg_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0024e b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00253 99 cdq 00254 f7 f9 idiv ecx ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00256 44 3b f8 cmp r15d, eax 00259 0f 8f 09 06 00 00 jg $LN241@load_jpeg_ $LN243@load_jpeg_: 0025f 44 8b c9 mov r9d, ecx 00262 45 0f af cf imul r9d, r15d ; 467 : if (a < 0 || b < 0) return 0; 00266 45 85 c9 test r9d, r9d 00269 0f 88 f9 05 00 00 js $LN241@load_jpeg_ 0026f 45 85 c0 test r8d, r8d 00272 0f 88 f0 05 00 00 js $LN241@load_jpeg_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00278 74 12 je SHORT $LN242@load_jpeg_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0027a b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0027f 99 cdq 00280 41 f7 f8 idiv r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00283 44 3b c8 cmp r9d, eax 00286 0f 8f dc 05 00 00 jg $LN241@load_jpeg_ $LN242@load_jpeg_: 0028c 8b c1 mov eax, ecx 0028e 41 0f af c0 imul eax, r8d 00292 41 0f af c7 imul eax, r15d ; 460 : return a <= INT_MAX - b; 00296 3d fe ff ff 7f cmp eax, 2147483646 ; 7ffffffeH ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0029b 0f 8f c7 05 00 00 jg $LN241@load_jpeg_ ; 509 : return stbi__malloc(a * b * c + add); 002a1 41 0f af c8 imul ecx, r8d 002a5 41 0f af cf imul ecx, r15d 002a9 ff c1 inc ecx 002ab 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 002ae ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } 002b4 48 8b 16 mov rdx, QWORD PTR [rsi] ; 438 : return STBI_MALLOC(size); 002b7 4c 8b e8 mov r13, rax ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } 002ba 48 85 c0 test rax, rax 002bd 0f 84 a8 05 00 00 je $LN240@load_jpeg_ ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { 002c3 33 c0 xor eax, eax 002c5 89 44 24 30 mov DWORD PTR j$1$[rsp], eax 002c9 39 42 04 cmp DWORD PTR [rdx+4], eax 002cc 0f 86 01 05 00 00 jbe $LN6@load_jpeg_ ; 3427 : if (is_rgb) { 002d2 4c 8b 64 24 68 mov r12, QWORD PTR coutput$4[rsp+24] 002d7 48 8b 6c 24 60 mov rbp, QWORD PTR coutput$4[rsp+16] 002dc 4c 8b 74 24 58 mov r14, QWORD PTR coutput$4[rsp+8] 002e1 48 8b 7c 24 50 mov rdi, QWORD PTR coutput$4[rsp] 002e6 4c 89 6c 24 38 mov QWORD PTR output$2$[rsp], r13 002eb 0f 1f 44 00 00 npad 5 $LL7@load_jpeg_: ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; 002f0 0f af 02 imul eax, DWORD PTR [rdx] 002f3 41 0f af c7 imul eax, r15d 002f7 45 33 ff xor r15d, r15d 002fa 8b d8 mov ebx, eax 002fc 49 03 dd add rbx, r13 002ff 48 89 5c 24 70 mov QWORD PTR out$1$[rsp], rbx ; 3410 : for (k = 0; k < decode_n; ++k) { 00304 4c 39 7c 24 48 cmp QWORD PTR tv3132[rsp], r15 00309 0f 86 c4 00 00 00 jbe $LN9@load_jpeg_ ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; 0030f 48 8b 5c 24 48 mov rbx, QWORD PTR tv3132[rsp] 00314 48 8d ae c0 46 00 00 lea rbp, QWORD PTR [rsi+18112] 0031b 48 8b 74 24 38 mov rsi, QWORD PTR output$2$[rsp] 00320 48 8d bc 24 c4 00 00 00 lea rdi, QWORD PTR res_comp$5[rsp+36] 00328 0f 1f 84 00 00 00 00 00 npad 8 $LL10@load_jpeg_: ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); 00330 8b 47 f8 mov eax, DWORD PTR [rdi-8] 00333 4c 8d 77 ec lea r14, QWORD PTR [rdi-20] 00337 d1 f8 sar eax, 1 00339 4c 8d 67 e4 lea r12, QWORD PTR [rdi-28] ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, 0033d 4d 8b ee mov r13, r14 00340 39 07 cmp DWORD PTR [rdi], eax 00342 7c 09 jl SHORT $LN89@load_jpeg_ 00344 4d 8b 04 24 mov r8, QWORD PTR [r12] 00348 49 8b d6 mov rdx, r14 0034b eb 06 jmp SHORT $LN92@load_jpeg_ $LN89@load_jpeg_: 0034d 4d 8b 06 mov r8, QWORD PTR [r14] 00350 49 8b d4 mov rdx, r12 $LN92@load_jpeg_: 00353 8b 47 f4 mov eax, DWORD PTR [rdi-12] 00356 44 8b 4f fc mov r9d, DWORD PTR [rdi-4] 0035a 48 8b 12 mov rdx, QWORD PTR [rdx] 0035d 48 8b 4d 28 mov rcx, QWORD PTR [rbp+40] 00361 89 44 24 20 mov DWORD PTR [rsp+32], eax 00365 ff 57 dc call QWORD PTR [rdi-36] 00368 4a 89 44 fc 50 mov QWORD PTR coutput$4[rsp+r15*8], rax ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { 0036d 8b 07 mov eax, DWORD PTR [rdi] 0036f ff c0 inc eax 00371 89 07 mov DWORD PTR [rdi], eax 00373 3b 47 f8 cmp eax, DWORD PTR [rdi-8] 00376 7c 23 jl SHORT $LN8@load_jpeg_ ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) 00378 ff 47 04 inc DWORD PTR [rdi+4] 0037b 8b 47 04 mov eax, DWORD PTR [rdi+4] 0037e 49 8b 4d 00 mov rcx, QWORD PTR [r13] 00382 c7 07 00 00 00 00 mov DWORD PTR [rdi], 0 00388 49 89 0c 24 mov QWORD PTR [r12], rcx 0038c 3b 45 00 cmp eax, DWORD PTR [rbp] 0038f 7d 0a jge SHORT $LN8@load_jpeg_ ; 3421 : r->line1 += z->img_comp[k].w2; 00391 48 63 45 04 movsxd rax, DWORD PTR [rbp+4] 00395 48 03 c1 add rax, rcx 00398 49 89 06 mov QWORD PTR [r14], rax $LN8@load_jpeg_: ; 3410 : for (k = 0; k < decode_n; ++k) { 0039b 49 ff c7 inc r15 0039e 48 83 c7 30 add rdi, 48 ; 00000030H 003a2 48 83 c5 60 add rbp, 96 ; 00000060H 003a6 4c 3b fb cmp r15, rbx 003a9 7c 85 jl SHORT $LL10@load_jpeg_ 003ab 4c 8b 64 24 68 mov r12, QWORD PTR coutput$4[rsp+24] 003b0 48 8b 6c 24 60 mov rbp, QWORD PTR coutput$4[rsp+16] 003b5 4c 8b 74 24 58 mov r14, QWORD PTR coutput$4[rsp+8] 003ba 48 8b 7c 24 50 mov rdi, QWORD PTR coutput$4[rsp] 003bf 48 8b 5c 24 70 mov rbx, QWORD PTR out$1$[rsp] 003c4 48 89 74 24 38 mov QWORD PTR output$2$[rsp], rsi 003c9 4c 8b 6c 24 38 mov r13, QWORD PTR output$2$[rsp] 003ce 48 8b 74 24 78 mov rsi, QWORD PTR z$GSCopy$1$[rsp] $LN9@load_jpeg_: ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { 003d3 4c 63 bc 24 e0 01 00 00 movsxd r15, DWORD PTR req_comp$[rsp] 003db 48 8b 06 mov rax, QWORD PTR [rsi] 003de 41 83 ff 03 cmp r15d, 3 003e2 0f 8c c9 01 00 00 jl $LN59@load_jpeg_ ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { 003e8 8b 48 08 mov ecx, DWORD PTR [rax+8] 003eb 83 f9 03 cmp ecx, 3 003ee 75 5e jne SHORT $LN61@load_jpeg_ ; 3427 : if (is_rgb) { 003f0 48 83 7c 24 40 00 cmp QWORD PTR tv3179[rsp], 0 003f6 74 34 je SHORT $LN63@load_jpeg_ ; 3428 : for (i = 0; i < z->s->img_x; ++i) { 003f8 33 d2 xor edx, edx 003fa 39 10 cmp DWORD PTR [rax], edx 003fc 0f 86 b5 03 00 00 jbe $LN5@load_jpeg_ $LL13@load_jpeg_: ; 3429 : out[0] = y[i]; 00402 0f b6 04 3a movzx eax, BYTE PTR [rdx+rdi] 00406 88 03 mov BYTE PTR [rbx], al ; 3430 : out[1] = coutput[1][i]; 00408 42 0f b6 04 32 movzx eax, BYTE PTR [rdx+r14] 0040d 88 43 01 mov BYTE PTR [rbx+1], al 00410 0f b6 04 2a movzx eax, BYTE PTR [rdx+rbp] 00414 ff c2 inc edx 00416 88 43 02 mov BYTE PTR [rbx+2], al ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; 00419 c6 43 03 ff mov BYTE PTR [rbx+3], 255 ; 000000ffH ; 3433 : out += n; 0041d 49 03 df add rbx, r15 00420 48 8b 06 mov rax, QWORD PTR [rsi] 00423 3b 10 cmp edx, DWORD PTR [rax] 00425 72 db jb SHORT $LL13@load_jpeg_ ; 3434 : } ; 3435 : } 00427 e9 8b 03 00 00 jmp $LN5@load_jpeg_ $LN63@load_jpeg_: ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); 0042c 8b 00 mov eax, DWORD PTR [rax] 0042e 4c 8b cd mov r9, rbp 00431 44 89 7c 24 28 mov DWORD PTR [rsp+40], r15d 00436 4d 8b c6 mov r8, r14 00439 48 8b d7 mov rdx, rdi 0043c 89 44 24 20 mov DWORD PTR [rsp+32], eax 00440 48 8b cb mov rcx, rbx 00443 ff 96 78 48 00 00 call QWORD PTR [rsi+18552] ; 3438 : } ; 3439 : } 00449 e9 69 03 00 00 jmp $LN5@load_jpeg_ $LN61@load_jpeg_: ; 3440 : else if (z->s->img_n == 4) { 0044e 83 f9 04 cmp ecx, 4 00451 0f 85 2a 01 00 00 jne $LN65@load_jpeg_ ; 3441 : if (z->app14_color_transform == 0) { // CMYK 00457 8b 8e 4c 48 00 00 mov ecx, DWORD PTR [rsi+18508] 0045d 85 c9 test ecx, ecx 0045f 75 75 jne SHORT $LN67@load_jpeg_ ; 3442 : for (i = 0; i < z->s->img_x; ++i) { 00461 45 33 c9 xor r9d, r9d 00464 44 39 08 cmp DWORD PTR [rax], r9d 00467 0f 86 4a 03 00 00 jbe $LN5@load_jpeg_ 0046d 0f 1f 00 npad 3 $LL16@load_jpeg_: ; 3343 : unsigned int t = x * y + 128; 00470 47 0f b6 04 21 movzx r8d, BYTE PTR [r9+r12] 00475 41 0f b6 0c 39 movzx ecx, BYTE PTR [r9+rdi] 0047a 41 0f af c8 imul ecx, r8d 0047e 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 00481 8b c1 mov eax, ecx 00483 c1 e8 08 shr eax, 8 00486 03 c1 add eax, ecx 00488 c1 e8 08 shr eax, 8 ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); 0048b 88 03 mov BYTE PTR [rbx], al ; 3343 : unsigned int t = x * y + 128; 0048d 43 0f b6 0c 31 movzx ecx, BYTE PTR [r9+r14] 00492 41 0f af c8 imul ecx, r8d 00496 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 00499 8b c1 mov eax, ecx 0049b c1 e8 08 shr eax, 8 0049e 03 c1 add eax, ecx 004a0 c1 e8 08 shr eax, 8 ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); 004a3 88 43 01 mov BYTE PTR [rbx+1], al ; 3343 : unsigned int t = x * y + 128; 004a6 41 0f b6 0c 29 movzx ecx, BYTE PTR [r9+rbp] ; 3442 : for (i = 0; i < z->s->img_x; ++i) { 004ab 41 ff c1 inc r9d ; 3447 : out[3] = 255; 004ae c6 43 03 ff mov BYTE PTR [rbx+3], 255 ; 000000ffH ; 3343 : unsigned int t = x * y + 128; 004b2 41 0f af c8 imul ecx, r8d 004b6 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 004b9 8b c1 mov eax, ecx 004bb c1 e8 08 shr eax, 8 004be 03 c1 add eax, ecx 004c0 c1 e8 08 shr eax, 8 ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); 004c3 88 43 02 mov BYTE PTR [rbx+2], al ; 3448 : out += n; 004c6 49 03 df add rbx, r15 004c9 48 8b 06 mov rax, QWORD PTR [rsi] 004cc 44 3b 08 cmp r9d, DWORD PTR [rax] 004cf 72 9f jb SHORT $LL16@load_jpeg_ ; 3449 : } ; 3450 : } 004d1 e9 e1 02 00 00 jmp $LN5@load_jpeg_ $LN67@load_jpeg_: ; 3451 : else if (z->app14_color_transform == 2) { // YCCK 004d6 8b 10 mov edx, DWORD PTR [rax] 004d8 83 f9 02 cmp ecx, 2 004db 48 8b 86 78 48 00 00 mov rax, QWORD PTR [rsi+18552] 004e2 4c 8b cd mov r9, rbp 004e5 44 89 7c 24 28 mov DWORD PTR [rsp+40], r15d 004ea 4d 8b c6 mov r8, r14 004ed 89 54 24 20 mov DWORD PTR [rsp+32], edx 004f1 48 8b cb mov rcx, rbx 004f4 48 8b d7 mov rdx, rdi 004f7 0f 85 7d 00 00 00 jne $LN69@load_jpeg_ ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); 004fd ff d0 call rax ; 3453 : for (i = 0; i < z->s->img_x; ++i) { 004ff 48 8b 06 mov rax, QWORD PTR [rsi] 00502 45 33 c0 xor r8d, r8d 00505 44 39 00 cmp DWORD PTR [rax], r8d 00508 0f 86 a9 02 00 00 jbe $LN5@load_jpeg_ 0050e 66 90 npad 2 $LL19@load_jpeg_: ; 3343 : unsigned int t = x * y + 128; 00510 43 0f b6 14 20 movzx edx, BYTE PTR [r8+r12] ; 3453 : for (i = 0; i < z->s->img_x; ++i) { 00515 41 ff c0 inc r8d ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); 00518 0f b6 03 movzx eax, BYTE PTR [rbx] 0051b f6 d0 not al ; 3343 : unsigned int t = x * y + 128; 0051d 0f b6 c8 movzx ecx, al 00520 0f af ca imul ecx, edx 00523 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 00526 8b c1 mov eax, ecx 00528 c1 e8 08 shr eax, 8 0052b 03 c1 add eax, ecx 0052d c1 e8 08 shr eax, 8 ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); 00530 88 03 mov BYTE PTR [rbx], al ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); 00532 0f b6 43 01 movzx eax, BYTE PTR [rbx+1] 00536 f6 d0 not al ; 3343 : unsigned int t = x * y + 128; 00538 0f b6 c8 movzx ecx, al 0053b 0f af ca imul ecx, edx 0053e 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 00541 8b c1 mov eax, ecx 00543 c1 e8 08 shr eax, 8 00546 03 c1 add eax, ecx 00548 c1 e8 08 shr eax, 8 ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); 0054b 88 43 01 mov BYTE PTR [rbx+1], al ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); 0054e 0f b6 43 02 movzx eax, BYTE PTR [rbx+2] 00552 f6 d0 not al ; 3343 : unsigned int t = x * y + 128; 00554 0f b6 c8 movzx ecx, al 00557 0f af ca imul ecx, edx 0055a 83 e9 80 sub ecx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 0055d 8b c1 mov eax, ecx 0055f c1 e8 08 shr eax, 8 00562 03 c1 add eax, ecx 00564 c1 e8 08 shr eax, 8 ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); 00567 88 43 02 mov BYTE PTR [rbx+2], al ; 3458 : out += n; 0056a 49 03 df add rbx, r15 0056d 48 8b 06 mov rax, QWORD PTR [rsi] 00570 44 3b 00 cmp r8d, DWORD PTR [rax] 00573 72 9b jb SHORT $LL19@load_jpeg_ ; 3459 : } ; 3460 : } 00575 e9 3d 02 00 00 jmp $LN5@load_jpeg_ $LN69@load_jpeg_: ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); 0057a ff d0 call rax ; 3463 : } ; 3464 : } 0057c e9 36 02 00 00 jmp $LN5@load_jpeg_ $LN65@load_jpeg_: ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { 00581 33 d2 xor edx, edx 00583 39 10 cmp DWORD PTR [rax], edx 00585 0f 86 2c 02 00 00 jbe $LN5@load_jpeg_ 0058b 0f 1f 44 00 00 npad 5 $LL22@load_jpeg_: ; 3467 : out[0] = out[1] = out[2] = y[i]; 00590 0f b6 0c 3a movzx ecx, BYTE PTR [rdx+rdi] 00594 ff c2 inc edx 00596 88 4b 02 mov BYTE PTR [rbx+2], cl 00599 88 4b 01 mov BYTE PTR [rbx+1], cl 0059c 88 0b mov BYTE PTR [rbx], cl ; 3468 : out[3] = 255; // not used if n==3 0059e c6 43 03 ff mov BYTE PTR [rbx+3], 255 ; 000000ffH ; 3469 : out += n; 005a2 49 03 df add rbx, r15 005a5 48 8b 06 mov rax, QWORD PTR [rsi] 005a8 3b 10 cmp edx, DWORD PTR [rax] 005aa 72 e4 jb SHORT $LL22@load_jpeg_ ; 3470 : } ; 3471 : } 005ac e9 06 02 00 00 jmp $LN5@load_jpeg_ $LN59@load_jpeg_: ; 3472 : else { ; 3473 : if (is_rgb) { 005b1 48 83 7c 24 40 00 cmp QWORD PTR tv3179[rsp], 0 005b7 0f 84 a5 00 00 00 je $LN71@load_jpeg_ ; 3474 : if (n == 1) 005bd 8b 08 mov ecx, DWORD PTR [rax] 005bf 45 33 c9 xor r9d, r9d 005c2 41 83 ff 01 cmp r15d, 1 005c6 75 46 jne SHORT $LN73@load_jpeg_ ; 3475 : for (i = 0; i < z->s->img_x; ++i) 005c8 85 c9 test ecx, ecx 005ca 0f 84 e7 01 00 00 je $LN5@load_jpeg_ $LL25@load_jpeg_: ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 005d0 43 0f b6 04 31 movzx eax, BYTE PTR [r9+r14] 005d5 48 8d 5b 01 lea rbx, QWORD PTR [rbx+1] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 005d9 44 69 c0 96 00 00 00 imul r8d, eax, 150 ; 00000096H ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 005e0 41 0f b6 04 29 movzx eax, BYTE PTR [r9+rbp] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 005e5 6b c8 1d imul ecx, eax, 29 ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 005e8 41 0f b6 04 39 movzx eax, BYTE PTR [r9+rdi] 005ed 41 ff c1 inc r9d ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 005f0 44 03 c1 add r8d, ecx 005f3 6b c8 4d imul ecx, eax, 77 ; 0000004dH 005f6 44 03 c1 add r8d, ecx 005f9 41 c1 e8 08 shr r8d, 8 ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 005fd 44 88 43 ff mov BYTE PTR [rbx-1], r8b 00601 48 8b 06 mov rax, QWORD PTR [rsi] 00604 44 3b 08 cmp r9d, DWORD PTR [rax] 00607 72 c7 jb SHORT $LL25@load_jpeg_ 00609 e9 a9 01 00 00 jmp $LN5@load_jpeg_ $LN73@load_jpeg_: ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { 0060e 85 c9 test ecx, ecx 00610 0f 84 a1 01 00 00 je $LN5@load_jpeg_ 00616 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL28@load_jpeg_: ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 00620 43 0f b6 04 31 movzx eax, BYTE PTR [r9+r14] 00625 48 8d 5b 02 lea rbx, QWORD PTR [rbx+2] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00629 44 69 c0 96 00 00 00 imul r8d, eax, 150 ; 00000096H ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 00630 41 0f b6 04 29 movzx eax, BYTE PTR [r9+rbp] ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00635 6b c8 1d imul ecx, eax, 29 ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 00638 41 0f b6 04 39 movzx eax, BYTE PTR [r9+rdi] 0063d 41 ff c1 inc r9d ; 3480 : out[1] = 255; 00640 c6 43 ff ff mov BYTE PTR [rbx-1], 255 ; 000000ffH ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 00644 44 03 c1 add r8d, ecx 00647 6b c8 4d imul ecx, eax, 77 ; 0000004dH 0064a 44 03 c1 add r8d, ecx 0064d 41 c1 e8 08 shr r8d, 8 ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); 00651 44 88 43 fe mov BYTE PTR [rbx-2], r8b 00655 48 8b 06 mov rax, QWORD PTR [rsi] 00658 44 3b 08 cmp r9d, DWORD PTR [rax] 0065b 72 c3 jb SHORT $LL28@load_jpeg_ ; 3481 : } ; 3482 : } ; 3483 : } 0065d e9 55 01 00 00 jmp $LN5@load_jpeg_ $LN71@load_jpeg_: ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { 00662 83 78 08 04 cmp DWORD PTR [rax+8], 4 00666 0f 85 f9 00 00 00 jne $LN238@load_jpeg_ 0066c 8b 8e 4c 48 00 00 mov ecx, DWORD PTR [rsi+18508] 00672 85 c9 test ecx, ecx 00674 0f 85 97 00 00 00 jne $LN221@load_jpeg_ ; 3485 : for (i = 0; i < z->s->img_x; ++i) { 0067a 45 33 d2 xor r10d, r10d 0067d 44 39 10 cmp DWORD PTR [rax], r10d 00680 0f 86 31 01 00 00 jbe $LN5@load_jpeg_ 00686 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL31@load_jpeg_: ; 3343 : unsigned int t = x * y + 128; 00690 43 0f b6 0c 22 movzx ecx, BYTE PTR [r10+r12] 00695 43 0f b6 14 32 movzx edx, BYTE PTR [r10+r14] 0069a 45 0f b6 04 2a movzx r8d, BYTE PTR [r10+rbp] 0069f 45 0f b6 0c 3a movzx r9d, BYTE PTR [r10+rdi] ; 3485 : for (i = 0; i < z->s->img_x; ++i) { 006a4 41 ff c2 inc r10d ; 3343 : unsigned int t = x * y + 128; 006a7 0f af d1 imul edx, ecx 006aa 44 0f af c1 imul r8d, ecx 006ae 44 0f af c9 imul r9d, ecx ; 3491 : out[1] = 255; 006b2 c6 43 01 ff mov BYTE PTR [rbx+1], 255 ; 000000ffH ; 3343 : unsigned int t = x * y + 128; 006b6 83 ea 80 sub edx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 006b9 8b c2 mov eax, edx ; 3343 : unsigned int t = x * y + 128; 006bb 41 83 e8 80 sub r8d, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 006bf c1 e8 08 shr eax, 8 ; 3343 : unsigned int t = x * y + 128; 006c2 41 83 e9 80 sub r9d, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 006c6 03 c2 add eax, edx 006c8 c1 e8 08 shr eax, 8 006cb 0f b6 c0 movzx eax, al ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 006ce 69 d0 96 00 00 00 imul edx, eax, 150 ; 00000096H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 006d4 41 8b c0 mov eax, r8d 006d7 c1 e8 08 shr eax, 8 006da 41 03 c0 add eax, r8d 006dd c1 e8 08 shr eax, 8 006e0 0f b6 c0 movzx eax, al ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 006e3 6b c8 1d imul ecx, eax, 29 ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 006e6 41 8b c1 mov eax, r9d 006e9 c1 e8 08 shr eax, 8 006ec 41 03 c1 add eax, r9d 006ef c1 e8 08 shr eax, 8 006f2 0f b6 c0 movzx eax, al ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); 006f5 03 d1 add edx, ecx 006f7 6b c8 4d imul ecx, eax, 77 ; 0000004dH 006fa 03 d1 add edx, ecx 006fc c1 ea 08 shr edx, 8 ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); 006ff 88 13 mov BYTE PTR [rbx], dl ; 3492 : out += n; 00701 49 03 df add rbx, r15 00704 48 8b 06 mov rax, QWORD PTR [rsi] 00707 44 3b 10 cmp r10d, DWORD PTR [rax] 0070a 72 84 jb SHORT $LL31@load_jpeg_ ; 3493 : } ; 3494 : } 0070c e9 a6 00 00 00 jmp $LN5@load_jpeg_ $LN221@load_jpeg_: ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { 00711 83 f9 02 cmp ecx, 2 00714 75 4f jne SHORT $LN238@load_jpeg_ ; 3496 : for (i = 0; i < z->s->img_x; ++i) { 00716 45 33 c0 xor r8d, r8d 00719 44 39 00 cmp DWORD PTR [rax], r8d 0071c 0f 86 95 00 00 00 jbe $LN5@load_jpeg_ 00722 0f 1f 40 00 66 66 0f 1f 84 00 00 00 00 00 npad 14 $LL34@load_jpeg_: ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); 00730 41 0f b6 04 38 movzx eax, BYTE PTR [r8+rdi] 00735 f6 d0 not al ; 3343 : unsigned int t = x * y + 128; 00737 0f b6 d0 movzx edx, al 0073a 43 0f b6 04 20 movzx eax, BYTE PTR [r8+r12] ; 3496 : for (i = 0; i < z->s->img_x; ++i) { 0073f 41 ff c0 inc r8d ; 3343 : unsigned int t = x * y + 128; 00742 0f af d0 imul edx, eax ; 3498 : out[1] = 255; 00745 c6 43 01 ff mov BYTE PTR [rbx+1], 255 ; 000000ffH ; 3343 : unsigned int t = x * y + 128; 00749 83 ea 80 sub edx, -128 ; ffffffffffffff80H ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); 0074c 8b c2 mov eax, edx 0074e c1 e8 08 shr eax, 8 00751 03 c2 add eax, edx 00753 c1 e8 08 shr eax, 8 ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); 00756 88 03 mov BYTE PTR [rbx], al ; 3499 : out += n; 00758 49 03 df add rbx, r15 0075b 48 8b 06 mov rax, QWORD PTR [rsi] 0075e 44 3b 00 cmp r8d, DWORD PTR [rax] 00761 72 cd jb SHORT $LL34@load_jpeg_ ; 3500 : } ; 3501 : } 00763 eb 52 jmp SHORT $LN5@load_jpeg_ $LN238@load_jpeg_: ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) 00765 8b 08 mov ecx, DWORD PTR [rax] 00767 33 d2 xor edx, edx 00769 41 83 ff 01 cmp r15d, 1 0076d 75 23 jne SHORT $LN79@load_jpeg_ ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; 0076f 85 c9 test ecx, ecx 00771 74 44 je SHORT $LN5@load_jpeg_ 00773 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL37@load_jpeg_: 00780 0f b6 04 3a movzx eax, BYTE PTR [rdx+rdi] 00784 88 04 1a mov BYTE PTR [rdx+rbx], al 00787 ff c2 inc edx 00789 48 8b 06 mov rax, QWORD PTR [rsi] 0078c 3b 10 cmp edx, DWORD PTR [rax] 0078e 72 f0 jb SHORT $LL37@load_jpeg_ 00790 eb 25 jmp SHORT $LN5@load_jpeg_ $LN79@load_jpeg_: ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } 00792 85 c9 test ecx, ecx 00794 74 21 je SHORT $LN5@load_jpeg_ 00796 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL40@load_jpeg_: 007a0 0f b6 0c 3a movzx ecx, BYTE PTR [rdx+rdi] 007a4 ff c2 inc edx 007a6 88 0b mov BYTE PTR [rbx], cl 007a8 c6 43 01 ff mov BYTE PTR [rbx+1], 255 ; 000000ffH 007ac 48 8d 5b 02 lea rbx, QWORD PTR [rbx+2] 007b0 48 8b 06 mov rax, QWORD PTR [rsi] 007b3 3b 10 cmp edx, DWORD PTR [rax] 007b5 72 e9 jb SHORT $LL40@load_jpeg_ $LN5@load_jpeg_: ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { 007b7 8b 44 24 30 mov eax, DWORD PTR j$1$[rsp] 007bb 48 8b 16 mov rdx, QWORD PTR [rsi] 007be ff c0 inc eax 007c0 89 44 24 30 mov DWORD PTR j$1$[rsp], eax 007c4 3b 42 04 cmp eax, DWORD PTR [rdx+4] 007c7 0f 82 23 fb ff ff jb $LL7@load_jpeg_ 007cd 41 bc 01 00 00 00 mov r12d, 1 $LN6@load_jpeg_: ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); 007d3 8b 52 08 mov edx, DWORD PTR [rdx+8] 007d6 45 33 c0 xor r8d, r8d 007d9 48 8b ce mov rcx, rsi 007dc e8 00 00 00 00 call stbi__free_jpeg_components ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; 007e1 48 8b 06 mov rax, QWORD PTR [rsi] 007e4 8b 08 mov ecx, DWORD PTR [rax] 007e6 48 8b 84 24 80 00 00 00 mov rax, QWORD PTR out_x$GSCopy$1$[rsp] 007ee 89 08 mov DWORD PTR [rax], ecx ; 3513 : *out_y = z->s->img_y; 007f0 48 8b 0e mov rcx, QWORD PTR [rsi] 007f3 48 8b 84 24 88 00 00 00 mov rax, QWORD PTR out_y$GSCopy$1$[rsp] 007fb 8b 51 04 mov edx, DWORD PTR [rcx+4] 007fe 89 10 mov DWORD PTR [rax], edx ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output 00800 48 8b 84 24 90 00 00 00 mov rax, QWORD PTR comp$GSCopy$1$[rsp] 00808 48 85 c0 test rax, rax 0080b 74 13 je SHORT $LN81@load_jpeg_ 0080d 48 8b 0e mov rcx, QWORD PTR [rsi] 00810 83 79 08 03 cmp DWORD PTR [rcx+8], 3 00814 b9 03 00 00 00 mov ecx, 3 00819 44 0f 4d e1 cmovge r12d, ecx 0081d 44 89 20 mov DWORD PTR [rax], r12d $LN81@load_jpeg_: ; 3515 : return output; 00820 49 8b c5 mov rax, r13 $LN305@load_jpeg_: 00823 48 8b 9c 24 98 01 00 00 mov rbx, QWORD PTR [rsp+408] 0082b 48 8b bc 24 88 01 00 00 mov rdi, QWORD PTR [rsp+392] 00833 48 8b ac 24 90 01 00 00 mov rbp, QWORD PTR [rsp+400] 0083b 4c 8b b4 24 78 01 00 00 mov r14, QWORD PTR [rsp+376] $LN301@load_jpeg_: 00843 4c 8b a4 24 80 01 00 00 mov r12, QWORD PTR [rsp+384] $LN1@load_jpeg_: ; 3516 : } ; 3517 : } 0084b 48 8b 8c 24 60 01 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00853 48 33 cc xor rcx, rsp 00856 e8 00 00 00 00 call __security_check_cookie 0085b 48 81 c4 a0 01 00 00 add rsp, 416 ; 000001a0H 00862 41 5f pop r15 00864 41 5d pop r13 00866 5e pop rsi 00867 c3 ret 0 $LN241@load_jpeg_: ; 508 : if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; 00868 48 8b 16 mov rdx, QWORD PTR [rsi] $LN240@load_jpeg_: ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); 0086b 8b 52 08 mov edx, DWORD PTR [rdx+8] 0086e 45 33 c0 xor r8d, r8d 00871 48 8b ce mov rcx, rsi 00874 e8 00 00 00 00 call stbi__free_jpeg_components ; 431 : stbi__g_failure_reason = str; 00879 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0087f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00888 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0088d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00891 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00898 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } 0089c 33 c0 xor eax, eax 0089e eb 83 jmp SHORT $LN305@load_jpeg_ $LN42@load_jpeg_: ; 431 : stbi__g_failure_reason = str; 008a0 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 008a6 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 008af b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 008b4 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 008b8 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@KBPNPPBJ@bad?5req_comp@ 008bf 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); 008c3 33 c0 xor eax, eax 008c5 eb 84 jmp SHORT $LN1@load_jpeg_ load_jpeg_image ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_load _TEXT SEGMENT s$ = 80 x$ = 88 y$ = 96 comp$ = 104 req_comp$ = 112 ri$dead$ = 120 stbi__jpeg_load PROC ; COMDAT ; 3520 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 56 push r14 00016 48 83 ec 40 sub rsp, 64 ; 00000040H 0001a 48 8b d9 mov rbx, rcx 0001d 49 8b f1 mov rsi, r9 ; 438 : return STBI_MALLOC(size); 00020 b9 88 48 00 00 mov ecx, 18568 ; 00004888H ; 3520 : { 00025 49 8b e8 mov rbp, r8 00028 4c 8b f2 mov r14, rdx ; 438 : return STBI_MALLOC(size); 0002b ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00031 48 8b f8 mov rdi, rax ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); 00034 48 85 c0 test rax, rax 00037 75 2a jne SHORT $LN2@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 00039 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00042 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00048 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 0004d 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 00051 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00058 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); 0005c 33 c0 xor eax, eax 0005e e9 9f 00 00 00 jmp $LN1@stbi__jpeg $LN2@stbi__jpeg: ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); 00063 48 8d 48 08 lea rcx, QWORD PTR [rax+8] 00067 33 d2 xor edx, edx 00069 41 b8 68 48 00 00 mov r8d, 18536 ; 00004868H 0006f e8 00 00 00 00 call memset ; 3305 : j->idct_block_kernel = stbi__idct_block; 00074 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_block ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; 0007b 48 89 1f mov QWORD PTR [rdi], rbx ; 3305 : j->idct_block_kernel = stbi__idct_block; 0007e 48 89 87 70 48 00 00 mov QWORD PTR [rdi+18544], rax ; 187 : __cpuid(info, 1); 00085 33 c9 xor ecx, ecx ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; 00087 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_row 0008e 48 89 87 78 48 00 00 mov QWORD PTR [rdi+18552], rax ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; 00095 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2 0009c 48 89 87 80 48 00 00 mov QWORD PTR [rdi+18560], rax ; 187 : __cpuid(info, 1); 000a3 b8 01 00 00 00 mov eax, 1 000a8 0f a2 cpuid ; 3310 : if (stbi__sse2_available()) { 000aa 0f ba e2 1a bt edx, 26 000ae 73 2a jae SHORT $LN9@stbi__jpeg ; 3311 : j->idct_block_kernel = stbi__idct_simd; 000b0 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_simd 000b7 48 89 87 70 48 00 00 mov QWORD PTR [rdi+18544], rax ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; 000be 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_simd 000c5 48 89 87 78 48 00 00 mov QWORD PTR [rdi+18552], rax ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; 000cc 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2_simd 000d3 48 89 87 80 48 00 00 mov QWORD PTR [rdi+18560], rax $LN9@stbi__jpeg: ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); 000da 8b 44 24 70 mov eax, DWORD PTR req_comp$[rsp] 000de 4c 8b ce mov r9, rsi 000e1 4c 8b c5 mov r8, rbp 000e4 89 44 24 20 mov DWORD PTR [rsp+32], eax 000e8 49 8b d6 mov rdx, r14 000eb 48 8b cf mov rcx, rdi 000ee e8 00 00 00 00 call load_jpeg_image ; 3529 : STBI_FREE(j); 000f3 48 8b cf mov rcx, rdi 000f6 48 8b d8 mov rbx, rax 000f9 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 3530 : return result; 000ff 48 8b c3 mov rax, rbx $LN1@stbi__jpeg: ; 3531 : } 00102 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 00107 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 0010c 48 8b 74 24 60 mov rsi, QWORD PTR [rsp+96] 00111 48 8b 7c 24 68 mov rdi, QWORD PTR [rsp+104] 00116 48 83 c4 40 add rsp, 64 ; 00000040H 0011a 41 5e pop r14 0011c c3 ret 0 stbi__jpeg_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__jpeg_test _TEXT SEGMENT s$ = 64 stbi__jpeg_test PROC ; COMDAT ; 3534 : { 00000 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 00005 57 push rdi 00006 48 83 ec 30 sub rsp, 48 ; 00000030H 0000a 48 8b f1 mov rsi, rcx ; 438 : return STBI_MALLOC(size); 0000d b9 88 48 00 00 mov ecx, 18568 ; 00004888H 00012 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00018 48 8b f8 mov rdi, rax ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); 0001b 48 85 c0 test rax, rax 0001e 75 30 jne SHORT $LN2@stbi__jpeg ; 431 : stbi__g_failure_reason = str; 00020 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00029 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 0002f ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 00034 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 00038 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 0003f 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); 00043 33 c0 xor eax, eax ; 3544 : return r; ; 3545 : } 00045 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] 0004a 48 83 c4 30 add rsp, 48 ; 00000030H 0004e 5f pop rdi 0004f c3 ret 0 $LN2@stbi__jpeg: ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); 00050 48 8d 48 08 lea rcx, QWORD PTR [rax+8] 00054 48 89 5c 24 40 mov QWORD PTR [rsp+64], rbx 00059 33 d2 xor edx, edx 0005b 41 b8 68 48 00 00 mov r8d, 18536 ; 00004868H 00061 e8 00 00 00 00 call memset ; 3305 : j->idct_block_kernel = stbi__idct_block; 00066 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_block ; 3539 : j->s = s; 0006d 48 89 37 mov QWORD PTR [rdi], rsi ; 3305 : j->idct_block_kernel = stbi__idct_block; 00070 48 89 87 70 48 00 00 mov QWORD PTR [rdi+18544], rax ; 187 : __cpuid(info, 1); 00077 33 c9 xor ecx, ecx ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; 00079 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_row 00080 48 89 87 78 48 00 00 mov QWORD PTR [rdi+18552], rax ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; 00087 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2 0008e 48 89 87 80 48 00 00 mov QWORD PTR [rdi+18560], rax ; 187 : __cpuid(info, 1); 00095 b8 01 00 00 00 mov eax, 1 0009a 0f a2 cpuid ; 3310 : if (stbi__sse2_available()) { 0009c 0f ba e2 1a bt edx, 26 000a0 73 2a jae SHORT $LN9@stbi__jpeg ; 3311 : j->idct_block_kernel = stbi__idct_simd; 000a2 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__idct_simd 000a9 48 89 87 70 48 00 00 mov QWORD PTR [rdi+18544], rax ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; 000b0 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__YCbCr_to_RGB_simd 000b7 48 89 87 78 48 00 00 mov QWORD PTR [rdi+18552], rax ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; 000be 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:stbi__resample_row_hv_2_simd 000c5 48 89 87 80 48 00 00 mov QWORD PTR [rdi+18560], rax $LN9@stbi__jpeg: ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); 000cc ba 01 00 00 00 mov edx, 1 000d1 48 8b cf mov rcx, rdi 000d4 e8 00 00 00 00 call stbi__decode_jpeg_header ; 342 : s->img_buffer = s->img_buffer_original; 000d9 48 8b 96 d0 00 00 00 mov rdx, QWORD PTR [rsi+208] ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); 000e0 48 8b cf mov rcx, rdi ; 342 : s->img_buffer = s->img_buffer_original; 000e3 48 89 96 c0 00 00 00 mov QWORD PTR [rsi+192], rdx ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); 000ea 8b d8 mov ebx, eax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 000ec 48 8b 96 d8 00 00 00 mov rdx, QWORD PTR [rsi+216] 000f3 48 89 96 c8 00 00 00 mov QWORD PTR [rsi+200], rdx ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); 000fa ff 15 00 00 00 00 call QWORD PTR __imp_free ; 3544 : return r; ; 3545 : } 00100 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] 00105 8b c3 mov eax, ebx 00107 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 0010c 48 83 c4 30 add rsp, 48 ; 00000030H 00110 5f pop rdi 00111 c3 ret 0 stbi__jpeg_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bitreverse16 _TEXT SEGMENT n$ = 8 stbi__bitreverse16 PROC ; COMDAT ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 00000 8b c1 mov eax, ecx 00002 81 e1 55 55 00 00 and ecx, 21845 ; 00005555H 00008 d1 f8 sar eax, 1 0000a 03 c9 add ecx, ecx 0000c 25 55 55 00 00 and eax, 21845 ; 00005555H 00011 0b c1 or eax, ecx ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); 00013 8b d0 mov edx, eax 00015 25 33 33 00 00 and eax, 13107 ; 00003333H 0001a c1 ea 02 shr edx, 2 0001d c1 e0 02 shl eax, 2 00020 81 e2 33 33 00 00 and edx, 13107 ; 00003333H 00026 0b d0 or edx, eax ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 00028 8b ca mov ecx, edx 0002a 81 e2 0f 0f 00 00 and edx, 3855 ; 00000f0fH 00030 c1 e9 04 shr ecx, 4 00033 81 e1 0f 0f 00 00 and ecx, 3855 ; 00000f0fH 00039 c1 e2 04 shl edx, 4 0003c 0b ca or ecx, edx ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 0003e 0f b6 c1 movzx eax, cl 00041 c1 e0 08 shl eax, 8 00044 c1 e9 08 shr ecx, 8 00047 0b c1 or eax, ecx ; 3604 : return n; ; 3605 : } 00049 c3 ret 0 stbi__bitreverse16 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bit_reverse _TEXT SEGMENT v$ = 8 bits$ = 16 stbi__bit_reverse PROC ; COMDAT ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 00000 8b c1 mov eax, ecx ; 3608 : { 00002 44 8b c2 mov r8d, edx ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 00005 d1 f8 sar eax, 1 00007 81 e1 55 55 00 00 and ecx, 21845 ; 00005555H 0000d 03 c9 add ecx, ecx 0000f 25 55 55 00 00 and eax, 21845 ; 00005555H 00014 0b c1 or eax, ecx ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); 00016 8b d0 mov edx, eax 00018 25 33 33 00 00 and eax, 13107 ; 00003333H 0001d c1 e0 02 shl eax, 2 00020 c1 ea 02 shr edx, 2 00023 81 e2 33 33 00 00 and edx, 13107 ; 00003333H 00029 0b d0 or edx, eax ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 0002b 8b ca mov ecx, edx 0002d 81 e2 0f 0f 00 00 and edx, 3855 ; 00000f0fH 00033 c1 e9 04 shr ecx, 4 00036 81 e1 0f 0f 00 00 and ecx, 3855 ; 00000f0fH 0003c c1 e2 04 shl edx, 4 0003f 0b ca or ecx, edx ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 00041 0f b6 c1 movzx eax, cl ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 00044 c1 e9 08 shr ecx, 8 ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 00047 c1 e0 08 shl eax, 8 0004a 0b c1 or eax, ecx ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 0004c b9 10 00 00 00 mov ecx, 16 00051 41 2b c8 sub ecx, r8d 00054 d3 f8 sar eax, cl ; 3613 : } 00056 c3 ret 0 stbi__bit_reverse ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zbuild_huffman _TEXT SEGMENT next_code$ = 32 sizes$ = 96 __$ArrayPad$ = 176 z$ = 240 sizelist$ = 248 num$ = 256 stbi__zbuild_huffman PROC ; COMDAT ; 3616 : { 00000 4c 8b dc mov r11, rsp 00003 53 push rbx 00004 55 push rbp 00005 57 push rdi 00006 41 56 push r14 00008 41 57 push r15 0000a 48 81 ec c0 00 00 00 sub rsp, 192 ; 000000c0H 00011 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00018 48 33 c4 xor rax, rsp 0001b 48 89 84 24 b0 00 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00023 0f 57 c0 xorps xmm0, xmm0 00026 45 8b f8 mov r15d, r8d ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); 00029 0f 11 44 24 60 movups XMMWORD PTR sizes$[rsp], xmm0 0002e 4c 8b f2 mov r14, rdx 00031 33 c0 xor eax, eax 00033 0f 11 44 24 70 movups XMMWORD PTR sizes$[rsp+16], xmm0 00038 33 ff xor edi, edi 0003a 41 89 43 b8 mov DWORD PTR [r11-72], eax ; 3622 : memset(z->fast, 0, sizeof(z->fast)); 0003e 33 d2 xor edx, edx 00040 41 b8 00 04 00 00 mov r8d, 1024 ; 00000400H 00046 41 0f 11 43 98 movups XMMWORD PTR [r11-104], xmm0 0004b 48 8b d9 mov rbx, rcx 0004e 8b ef mov ebp, edi 00050 41 0f 11 43 a8 movups XMMWORD PTR [r11-88], xmm0 00055 e8 00 00 00 00 call memset ; 3623 : for (i = 0; i < num; ++i) 0005a 45 85 ff test r15d, r15d 0005d 7e 22 jle SHORT $LN3@stbi__zbui ; 3616 : { 0005f 49 8b ce mov rcx, r14 00062 41 8b d7 mov edx, r15d 00065 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL4@stbi__zbui: ; 3624 : ++sizes[sizelist[i]]; 00070 0f b6 01 movzx eax, BYTE PTR [rcx] 00073 48 8d 49 01 lea rcx, QWORD PTR [rcx+1] 00077 ff 44 84 60 inc DWORD PTR sizes$[rsp+rax*4] 0007b 48 83 ea 01 sub rdx, 1 0007f 75 ef jne SHORT $LL4@stbi__zbui $LN3@stbi__zbui: ; 3625 : sizes[0] = 0; 00081 89 7c 24 60 mov DWORD PTR sizes$[rsp], edi ; 3626 : for (i = 1; i < 16; ++i) 00085 b9 01 00 00 00 mov ecx, 1 0008a 66 0f 1f 44 00 00 npad 6 $LL7@stbi__zbui: ; 3627 : if (sizes[i] > (1 << i)) 00090 48 63 d1 movsxd rdx, ecx 00093 b8 01 00 00 00 mov eax, 1 00098 d3 e0 shl eax, cl 0009a 39 44 94 60 cmp DWORD PTR sizes$[rsp+rdx*4], eax 0009e 0f 8f d5 01 00 00 jg $LN35@stbi__zbui ; 3626 : for (i = 1; i < 16; ++i) 000a4 ff c1 inc ecx 000a6 83 f9 10 cmp ecx, 16 000a9 7c e5 jl SHORT $LL7@stbi__zbui ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { 000ab 41 ba 01 00 00 00 mov r10d, 1 000b1 48 89 b4 24 00 01 00 00 mov QWORD PTR [rsp+256], rsi 000b9 44 8b c7 mov r8d, edi 000bc 45 8d 5a 0e lea r11d, QWORD PTR [r10+14] $LL10@stbi__zbui: ; 3631 : next_code[i] = code; 000c0 4d 63 ca movsxd r9, r10d ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); 000c3 42 8b 74 8c 60 mov esi, DWORD PTR sizes$[rsp+r9*4] 000c8 46 89 44 8c 20 mov DWORD PTR next_code$[rsp+r9*4], r8d 000cd 66 46 89 84 4b 00 04 00 00 mov WORD PTR [rbx+r9*2+1024], r8w 000d6 44 03 c6 add r8d, esi 000d9 66 42 89 ac 4b 64 04 00 00 mov WORD PTR [rbx+r9*2+1124], bp ; 3635 : if (sizes[i]) 000e2 85 f6 test esi, esi 000e4 74 16 je SHORT $LN18@stbi__zbui ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); 000e6 41 8b ca mov ecx, r10d 000e9 41 8d 40 ff lea eax, DWORD PTR [r8-1] 000ed ba 01 00 00 00 mov edx, 1 000f2 d3 e2 shl edx, cl 000f4 3b c2 cmp eax, edx 000f6 0f 8d 56 01 00 00 jge $LN36@stbi__zbui $LN18@stbi__zbui: ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop 000fc 41 8b cb mov ecx, r11d 000ff 41 8b c0 mov eax, r8d 00102 d3 e0 shl eax, cl ; 3638 : code <<= 1; 00104 45 03 c0 add r8d, r8d ; 3639 : k += sizes[i]; 00107 03 ee add ebp, esi 00109 42 89 84 8b 20 04 00 00 mov DWORD PTR [rbx+r9*4+1056], eax 00111 41 ff c2 inc r10d 00114 41 ff cb dec r11d 00117 45 85 db test r11d, r11d 0011a 7f a4 jg SHORT $LL10@stbi__zbui ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel 0011c c7 83 60 04 00 00 00 00 01 00 mov DWORD PTR [rbx+1120], 65536 ; 00010000H ; 3642 : for (i = 0; i < num; ++i) { 00126 45 85 ff test r15d, r15d 00129 0f 8e f7 00 00 00 jle $LN12@stbi__zbui 0012f 90 npad 1 $LL13@stbi__zbui: ; 3643 : int s = sizelist[i]; 00130 45 0f b6 0e movzx r9d, BYTE PTR [r14] ; 3644 : if (s) { 00134 45 85 c9 test r9d, r9d 00137 0f 84 db 00 00 00 je $LN11@stbi__zbui ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; 0013d 42 0f b7 84 4b 00 04 00 00 movzx eax, WORD PTR [rbx+r9*2+1024] 00146 4c 8d 5c 24 20 lea r11, QWORD PTR next_code$[rsp] 0014b 42 0f b7 8c 4b 64 04 00 00 movzx ecx, WORD PTR [rbx+r9*2+1124] 00154 4f 8d 1c 8b lea r11, QWORD PTR [r11+r9*4] 00158 45 8b 13 mov r10d, DWORD PTR [r11] 0015b 2b c8 sub ecx, eax ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); 0015d 45 0f b7 c1 movzx r8d, r9w 00161 66 41 c1 e0 09 shl r8w, 9 00166 66 44 0b c7 or r8w, di 0016a 41 8d 04 0a lea eax, DWORD PTR [r10+rcx] ; 3647 : z->size[c] = (stbi_uc)s; 0016e 48 98 cdqe 00170 44 88 8c 18 84 04 00 00 mov BYTE PTR [rax+rbx+1156], r9b ; 3648 : z->value[c] = (stbi__uint16)i; 00178 66 89 bc 43 a4 05 00 00 mov WORD PTR [rbx+rax*2+1444], di ; 3649 : if (s <= STBI__ZFAST_BITS) { 00180 41 83 f9 09 cmp r9d, 9 00184 0f 87 87 00 00 00 ja $LN15@stbi__zbui ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 0018a 41 8b ca mov ecx, r10d 0018d 41 8b c2 mov eax, r10d 00190 25 55 55 00 00 and eax, 21845 ; 00005555H 00195 d1 f9 sar ecx, 1 00197 03 c0 add eax, eax 00199 81 e1 55 55 00 00 and ecx, 21845 ; 00005555H 0019f 0b c8 or ecx, eax ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); 001a1 8b c1 mov eax, ecx 001a3 81 e1 33 33 00 00 and ecx, 13107 ; 00003333H 001a9 c1 e8 02 shr eax, 2 001ac 25 33 33 00 00 and eax, 13107 ; 00003333H 001b1 c1 e1 02 shl ecx, 2 001b4 0b c1 or eax, ecx ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 001b6 b9 10 00 00 00 mov ecx, 16 ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 001bb 8b d0 mov edx, eax ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 001bd 41 2b c9 sub ecx, r9d ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 001c0 25 0f 0f 00 00 and eax, 3855 ; 00000f0fH 001c5 c1 ea 04 shr edx, 4 001c8 c1 e0 04 shl eax, 4 001cb 81 e2 0f 0f 00 00 and edx, 3855 ; 00000f0fH 001d1 0b d0 or edx, eax ; 3650 : int j = stbi__bit_reverse(next_code[s], s); 001d3 8b c2 mov eax, edx ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 001d5 0f b6 d2 movzx edx, dl ; 3650 : int j = stbi__bit_reverse(next_code[s], s); 001d8 c1 e8 08 shr eax, 8 ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 001db c1 e2 08 shl edx, 8 001de 0b c2 or eax, edx ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 001e0 d3 f8 sar eax, cl ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { 001e2 3d 00 02 00 00 cmp eax, 512 ; 00000200H 001e7 7d 28 jge SHORT $LN15@stbi__zbui 001e9 41 8b c9 mov ecx, r9d 001ec ba 01 00 00 00 mov edx, 1 001f1 d3 e2 shl edx, cl 001f3 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL14@stbi__zbui: ; 3652 : z->fast[j] = fastv; 00200 48 63 c8 movsxd rcx, eax ; 3653 : j += (1 << s); 00203 03 c2 add eax, edx 00205 66 44 89 04 4b mov WORD PTR [rbx+rcx*2], r8w 0020a 3d 00 02 00 00 cmp eax, 512 ; 00000200H 0020f 7c ef jl SHORT $LL14@stbi__zbui $LN15@stbi__zbui: ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; 00211 41 8d 4a 01 lea ecx, DWORD PTR [r10+1] 00215 41 89 0b mov DWORD PTR [r11], ecx $LN11@stbi__zbui: ; 3642 : for (i = 0; i < num; ++i) { 00218 ff c7 inc edi 0021a 49 ff c6 inc r14 0021d 41 3b ff cmp edi, r15d 00220 0f 8c 0a ff ff ff jl $LL13@stbi__zbui $LN12@stbi__zbui: ; 3657 : } ; 3658 : } ; 3659 : return 1; 00226 b8 01 00 00 00 mov eax, 1 $LN62@stbi__zbui: 0022b 48 8b b4 24 00 01 00 00 mov rsi, QWORD PTR [rsp+256] $LN1@stbi__zbui: ; 3660 : } 00233 48 8b 8c 24 b0 00 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0023b 48 33 cc xor rcx, rsp 0023e e8 00 00 00 00 call __security_check_cookie 00243 48 81 c4 c0 00 00 00 add rsp, 192 ; 000000c0H 0024a 41 5f pop r15 0024c 41 5e pop r14 0024e 5f pop rdi 0024f 5d pop rbp 00250 5b pop rbx 00251 c3 ret 0 $LN36@stbi__zbui: ; 431 : stbi__g_failure_reason = str; 00252 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00258 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00261 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00266 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0026a 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MDNKOBMC@bad?5codelengths@ 00271 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); 00275 33 c0 xor eax, eax 00277 eb b2 jmp SHORT $LN62@stbi__zbui $LN35@stbi__zbui: ; 431 : stbi__g_failure_reason = str; 00279 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0027f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00288 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0028d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00291 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09EOHLEIKL@bad?5sizes@ 00298 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); 0029c 33 c0 xor eax, eax 0029e eb 93 jmp SHORT $LN1@stbi__zbui stbi__zbuild_huffman ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zeof _TEXT SEGMENT z$ = 8 stbi__zeof PROC ; COMDAT ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00000 48 8b 51 08 mov rdx, QWORD PTR [rcx+8] 00004 33 c0 xor eax, eax 00006 48 39 11 cmp QWORD PTR [rcx], rdx 00009 0f 93 c0 setae al ; 3685 : } 0000c c3 ret 0 stbi__zeof ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zget8 _TEXT SEGMENT z$ = 8 stbi__zget8 PROC ; COMDAT ; 3688 : { 00000 48 8b d1 mov rdx, rcx ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00003 48 8b 09 mov rcx, QWORD PTR [rcx] 00006 48 3b 4a 08 cmp rcx, QWORD PTR [rdx+8] ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0000a 72 03 jb SHORT $LN3@stbi__zget 0000c 32 c0 xor al, al ; 3690 : } 0000e c3 ret 0 $LN3@stbi__zget: ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0000f 0f b6 01 movzx eax, BYTE PTR [rcx] 00012 48 ff c1 inc rcx 00015 48 89 0a mov QWORD PTR [rdx], rcx ; 3690 : } 00018 c3 ret 0 stbi__zget8 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__fill_bits _TEXT SEGMENT z$ = 8 stbi__fill_bits PROC ; COMDAT ; 3693 : { 00000 48 8b c1 mov rax, rcx 00003 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL4@stbi__fill: ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00010 44 8b 40 10 mov r8d, DWORD PTR [rax+16] 00014 ba 01 00 00 00 mov edx, 1 00019 44 8b 48 14 mov r9d, DWORD PTR [rax+20] 0001d 41 8b c8 mov ecx, r8d 00020 d3 e2 shl edx, cl 00022 44 3b ca cmp r9d, edx 00025 73 31 jae SHORT $LN14@stbi__fill ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00027 48 8b 08 mov rcx, QWORD PTR [rax] 0002a 48 3b 48 08 cmp rcx, QWORD PTR [rax+8] ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0002e 72 04 jb SHORT $LN9@stbi__fill 00030 32 d2 xor dl, dl 00032 eb 09 jmp SHORT $LN10@stbi__fill $LN9@stbi__fill: 00034 0f b6 11 movzx edx, BYTE PTR [rcx] 00037 48 ff c1 inc rcx 0003a 48 89 08 mov QWORD PTR [rax], rcx $LN10@stbi__fill: ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 0003d 0f b6 d2 movzx edx, dl 00040 41 8b c8 mov ecx, r8d 00043 d3 e2 shl edx, cl ; 3700 : z->num_bits += 8; 00045 41 8d 48 08 lea ecx, DWORD PTR [r8+8] 00049 41 0b d1 or edx, r9d 0004c 89 48 10 mov DWORD PTR [rax+16], ecx 0004f 89 50 14 mov DWORD PTR [rax+20], edx ; 3701 : } while (z->num_bits <= 24); 00052 83 f9 18 cmp ecx, 24 00055 7e b9 jle SHORT $LL4@stbi__fill ; 3702 : } 00057 c3 ret 0 $LN14@stbi__fill: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00058 48 8b 48 08 mov rcx, QWORD PTR [rax+8] 0005c 48 89 08 mov QWORD PTR [rax], rcx ; 3702 : } 0005f c3 ret 0 stbi__fill_bits ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zreceive _TEXT SEGMENT z$ = 16 n$ = 24 stbi__zreceive PROC ; COMDAT ; 3705 : { 00000 40 57 push rdi ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00002 8b 41 10 mov eax, DWORD PTR [rcx+16] 00005 8b fa mov edi, edx 00007 4c 8b c9 mov r9, rcx 0000a 41 ba 01 00 00 00 mov r10d, 1 00010 3b c2 cmp eax, edx 00012 7d 6d jge SHORT $LN6@stbi__zrec ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00014 8b 51 14 mov edx, DWORD PTR [rcx+20] ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00017 44 8b d8 mov r11d, eax ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0001a 8b c8 mov ecx, eax 0001c 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00021 44 8b c0 mov r8d, eax 00024 41 8b c2 mov eax, r10d 00027 d3 e0 shl eax, cl 00029 3b d0 cmp edx, eax 0002b 73 45 jae SHORT $LN17@stbi__zrec 0002d 49 8b 59 08 mov rbx, QWORD PTR [r9+8] $LL7@stbi__zrec: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00031 49 8b 01 mov rax, QWORD PTR [r9] 00034 48 3b c3 cmp rax, rbx ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00037 72 04 jb SHORT $LN12@stbi__zrec 00039 32 c9 xor cl, cl 0003b eb 09 jmp SHORT $LN13@stbi__zrec $LN12@stbi__zrec: 0003d 0f b6 08 movzx ecx, BYTE PTR [rax] 00040 48 ff c0 inc rax 00043 49 89 01 mov QWORD PTR [r9], rax $LN13@stbi__zrec: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00046 0f b6 c1 movzx eax, cl 00049 41 8b cb mov ecx, r11d 0004c d3 e0 shl eax, cl 0004e 0b d0 or edx, eax ; 3700 : z->num_bits += 8; 00050 41 8d 43 08 lea eax, DWORD PTR [r11+8] 00054 41 89 51 14 mov DWORD PTR [r9+20], edx 00058 41 89 41 10 mov DWORD PTR [r9+16], eax ; 3701 : } while (z->num_bits <= 24); 0005c 83 f8 18 cmp eax, 24 0005f 7f 1b jg SHORT $LN25@stbi__zrec 00061 44 8b d8 mov r11d, eax 00064 44 8b c0 mov r8d, eax 00067 8b c8 mov ecx, eax 00069 41 8b c2 mov eax, r10d 0006c d3 e0 shl eax, cl 0006e 3b d0 cmp edx, eax 00070 72 bf jb SHORT $LL7@stbi__zrec $LN17@stbi__zrec: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00072 49 8b 41 08 mov rax, QWORD PTR [r9+8] 00076 49 89 01 mov QWORD PTR [r9], rax 00079 41 8b c0 mov eax, r8d $LN25@stbi__zrec: 0007c 48 8b 5c 24 10 mov rbx, QWORD PTR [rsp+16] $LN6@stbi__zrec: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 00081 45 8b 41 14 mov r8d, DWORD PTR [r9+20] ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; 00085 2b c7 sub eax, edi 00087 8b cf mov ecx, edi 00089 41 89 41 10 mov DWORD PTR [r9+16], eax 0008d 41 d3 e2 shl r10d, cl 00090 41 8b d0 mov edx, r8d 00093 d3 ea shr edx, cl 00095 41 89 51 14 mov DWORD PTR [r9+20], edx 00099 41 8d 42 ff lea eax, DWORD PTR [r10-1] 0009d 41 23 c0 and eax, r8d ; 3711 : return k; ; 3712 : } 000a0 5f pop rdi 000a1 c3 ret 0 stbi__zreceive ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zhuffman_decode_slowpath _TEXT SEGMENT a$ = 8 z$ = 16 stbi__zhuffman_decode_slowpath PROC ; COMDAT ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); 00000 44 8b 51 14 mov r10d, DWORD PTR [rcx+20] ; 3715 : { 00004 4c 8b d9 mov r11, rcx ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 00007 45 8b c2 mov r8d, r10d 0000a 41 8b c2 mov eax, r10d 0000d 41 d1 f8 sar r8d, 1 00010 25 55 55 00 00 and eax, 21845 ; 00005555H 00015 03 c0 add eax, eax 00017 41 81 e0 55 55 00 00 and r8d, 21845 ; 00005555H 0001e 44 0b c0 or r8d, eax ; 3715 : { 00021 4c 8b ca mov r9, rdx ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); 00024 41 8b c8 mov ecx, r8d 00027 41 81 e0 33 33 00 00 and r8d, 13107 ; 00003333H 0002e c1 e9 02 shr ecx, 2 00031 81 e1 33 33 00 00 and ecx, 13107 ; 00003333H 00037 41 c1 e0 02 shl r8d, 2 0003b 41 0b c8 or ecx, r8d ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 0003e 8b c1 mov eax, ecx 00040 81 e1 0f 0f 00 00 and ecx, 3855 ; 00000f0fH 00046 c1 e8 04 shr eax, 4 00049 25 0f 0f 00 00 and eax, 3855 ; 00000f0fH 0004e c1 e1 04 shl ecx, 4 00051 0b c1 or eax, ecx ; 3721 : if (k < z->maxcode[s]) 00053 48 8d 8a 48 04 00 00 lea rcx, QWORD PTR [rdx+1096] ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 0005a 44 0f b6 c0 movzx r8d, al 0005e c1 e8 08 shr eax, 8 00061 41 c1 e0 08 shl r8d, 8 00065 44 0b c0 or r8d, eax ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) 00068 b8 0a 00 00 00 mov eax, 10 ; 3721 : if (k < z->maxcode[s]) 0006d 44 3b 01 cmp r8d, DWORD PTR [rcx] 00070 7c 10 jl SHORT $LN6@stbi__zhuf $LL4@stbi__zhuf: ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) 00072 ff c0 inc eax 00074 48 8d 49 04 lea rcx, QWORD PTR [rcx+4] ; 3721 : if (k < z->maxcode[s]) 00078 44 3b 01 cmp r8d, DWORD PTR [rcx] 0007b 7d f5 jge SHORT $LL4@stbi__zhuf ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! 0007d 83 f8 10 cmp eax, 16 00080 7d 55 jge SHORT $LN20@stbi__zhuf $LN6@stbi__zhuf: ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; 00082 48 63 d0 movsxd rdx, eax 00085 b9 10 00 00 00 mov ecx, 16 0008a 2b c8 sub ecx, eax 0008c 41 d3 f8 sar r8d, cl 0008f 41 0f b7 8c 51 00 04 00 00 movzx ecx, WORD PTR [r9+rdx*2+1024] 00098 44 2b c1 sub r8d, ecx 0009b 41 0f b7 8c 51 64 04 00 00 movzx ecx, WORD PTR [r9+rdx*2+1124] 000a4 44 03 c1 add r8d, ecx ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! 000a7 41 81 f8 20 01 00 00 cmp r8d, 288 ; 00000120H 000ae 7d 27 jge SHORT $LN20@stbi__zhuf ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. 000b0 49 63 d0 movsxd rdx, r8d 000b3 42 0f b6 8c 0a 84 04 00 00 movzx ecx, BYTE PTR [rdx+r9+1156] 000bc 3b c8 cmp ecx, eax 000be 75 17 jne SHORT $LN20@stbi__zhuf ; 3728 : a->code_buffer >>= s; 000c0 8b c8 mov ecx, eax 000c2 41 d3 ea shr r10d, cl ; 3729 : a->num_bits -= s; 000c5 41 29 43 10 sub DWORD PTR [r11+16], eax 000c9 45 89 53 14 mov DWORD PTR [r11+20], r10d ; 3730 : return z->value[b]; 000cd 41 0f b7 84 51 a4 05 00 00 movzx eax, WORD PTR [r9+rdx*2+1444] ; 3731 : } 000d6 c3 ret 0 $LN20@stbi__zhuf: ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. 000d7 b8 ff ff ff ff mov eax, -1 ; 3731 : } 000dc c3 ret 0 stbi__zhuffman_decode_slowpath ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zhuffman_decode _TEXT SEGMENT a$ = 48 z$ = 56 stbi__zhuffman_decode PROC ; COMDAT ; 3734 : { 00000 40 57 push rdi 00002 48 83 ec 20 sub rsp, 32 ; 00000020H ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { 00006 44 8b 41 10 mov r8d, DWORD PTR [rcx+16] 0000a 48 8b fa mov rdi, rdx 0000d 4c 8b c9 mov r9, rcx 00010 41 83 f8 10 cmp r8d, 16 00014 7d 77 jge SHORT $LN10@stbi__zhuf ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00016 48 8b 01 mov rax, QWORD PTR [rcx] 00019 4c 8b 59 08 mov r11, QWORD PTR [rcx+8] 0001d 49 3b c3 cmp rax, r11 ; 3737 : if (stbi__zeof(a)) { 00020 72 0b jb SHORT $LN22@stbi__zhuf ; 3738 : return -1; /* report error for unexpected end of data. */ 00022 b8 ff ff ff ff mov eax, -1 ; 3750 : } 00027 48 83 c4 20 add rsp, 32 ; 00000020H 0002b 5f pop rdi 0002c c3 ret 0 $LN22@stbi__zhuf: 0002d 48 89 5c 24 30 mov QWORD PTR [rsp+48], rbx ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00032 ba 01 00 00 00 mov edx, 1 00037 8b 59 14 mov ebx, DWORD PTR [rcx+20] ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0003a 45 8b d0 mov r10d, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0003d 41 8b c8 mov ecx, r8d 00040 d3 e2 shl edx, cl 00042 3b da cmp ebx, edx 00044 73 3f jae SHORT $LN21@stbi__zhuf $LL11@stbi__zhuf: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00046 49 3b c3 cmp rax, r11 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00049 72 04 jb SHORT $LN16@stbi__zhuf 0004b 32 c9 xor cl, cl 0004d eb 09 jmp SHORT $LN17@stbi__zhuf $LN16@stbi__zhuf: 0004f 0f b6 08 movzx ecx, BYTE PTR [rax] 00052 48 ff c0 inc rax 00055 49 89 01 mov QWORD PTR [r9], rax $LN17@stbi__zhuf: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00058 0f b6 d1 movzx edx, cl ; 3700 : z->num_bits += 8; 0005b 45 8d 42 08 lea r8d, DWORD PTR [r10+8] 0005f 41 8b ca mov ecx, r10d 00062 45 89 41 10 mov DWORD PTR [r9+16], r8d 00066 d3 e2 shl edx, cl 00068 0b da or ebx, edx 0006a 41 89 59 14 mov DWORD PTR [r9+20], ebx ; 3701 : } while (z->num_bits <= 24); 0006e 41 83 f8 18 cmp r8d, 24 00072 7f 14 jg SHORT $LN32@stbi__zhuf ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00074 41 8b c8 mov ecx, r8d 00077 ba 01 00 00 00 mov edx, 1 0007c d3 e2 shl edx, cl ; 3701 : } while (z->num_bits <= 24); 0007e 45 8b d0 mov r10d, r8d 00081 3b da cmp ebx, edx 00083 72 c1 jb SHORT $LL11@stbi__zhuf $LN21@stbi__zhuf: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00085 4d 89 19 mov QWORD PTR [r9], r11 $LN32@stbi__zhuf: 00088 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] $LN10@stbi__zhuf: ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; 0008d 41 8b 51 14 mov edx, DWORD PTR [r9+20] 00091 8b c2 mov eax, edx 00093 25 ff 01 00 00 and eax, 511 ; 000001ffH 00098 0f b7 04 47 movzx eax, WORD PTR [rdi+rax*2] ; 3743 : if (b) { 0009c 85 c0 test eax, eax 0009e 74 1d je SHORT $LN4@stbi__zhuf ; 3744 : s = b >> 9; 000a0 8b c8 mov ecx, eax 000a2 c1 e9 09 shr ecx, 9 ; 3745 : a->code_buffer >>= s; 000a5 d3 ea shr edx, cl ; 3746 : a->num_bits -= s; 000a7 44 2b c1 sub r8d, ecx 000aa 41 89 51 14 mov DWORD PTR [r9+20], edx ; 3747 : return b & 511; 000ae 25 ff 01 00 00 and eax, 511 ; 000001ffH 000b3 45 89 41 10 mov DWORD PTR [r9+16], r8d ; 3750 : } 000b7 48 83 c4 20 add rsp, 32 ; 00000020H 000bb 5f pop rdi 000bc c3 ret 0 $LN4@stbi__zhuf: ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); 000bd 48 8b d7 mov rdx, rdi 000c0 49 8b c9 mov rcx, r9 ; 3750 : } 000c3 48 83 c4 20 add rsp, 32 ; 00000020H 000c7 5f pop rdi ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); 000c8 e9 00 00 00 00 jmp stbi__zhuffman_decode_slowpath stbi__zhuffman_decode ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__zexpand _TEXT SEGMENT z$ = 48 zout$ = 56 n$ = 64 stbi__zexpand PROC ; COMDAT ; 3753 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); 0000a 83 79 30 00 cmp DWORD PTR [rcx+48], 0 0000e 48 8b fa mov rdi, rdx 00011 48 8b d9 mov rbx, rcx 00014 48 89 51 18 mov QWORD PTR [rcx+24], rdx 00018 75 30 jne SHORT $LN4@stbi__zexp ; 431 : stbi__g_failure_reason = str; 0001a 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00020 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00029 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0002e 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00032 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BE@IBFIPFO@output?5buffer?5limit@ 00039 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); 0003d 33 c0 xor eax, eax ; 3772 : } 0003f 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 00044 48 83 c4 20 add rsp, 32 ; 00000020H 00048 5f pop rdi 00049 c3 ret 0 $LN4@stbi__zexp: ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); 0004a 2b 79 20 sub edi, DWORD PTR [rcx+32] ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); 0004d 8b 49 28 mov ecx, DWORD PTR [rcx+40] ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); 00050 8b c7 mov eax, edi 00052 2b 4b 20 sub ecx, DWORD PTR [rbx+32] 00055 f7 d0 not eax 00057 41 3b c0 cmp eax, r8d 0005a 73 30 jae SHORT $LN17@stbi__zexp $LN18@stbi__zexp: ; 3772 : } 0005c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00062 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0006b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00070 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00074 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 0007b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 0007f 33 c0 xor eax, eax 00081 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 00086 48 83 c4 20 add rsp, 32 ; 00000020H 0008a 5f pop rdi 0008b c3 ret 0 $LN17@stbi__zexp: ; 3761 : while (cur + n > limit) { 0008c 42 8d 04 07 lea eax, DWORD PTR [rdi+r8] 00090 3b c1 cmp eax, ecx 00092 76 0e jbe SHORT $LN3@stbi__zexp $LL2@stbi__zexp: ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); 00094 81 f9 ff ff ff 7f cmp ecx, 2147483647 ; 7fffffffH 0009a 77 c0 ja SHORT $LN18@stbi__zexp ; 3763 : limit *= 2; 0009c 03 c9 add ecx, ecx 0009e 3b c1 cmp eax, ecx 000a0 77 f2 ja SHORT $LL2@stbi__zexp $LN3@stbi__zexp: ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); 000a2 8b d1 mov edx, ecx 000a4 48 89 74 24 30 mov QWORD PTR [rsp+48], rsi 000a9 8b f1 mov esi, ecx 000ab 48 8b 4b 20 mov rcx, QWORD PTR [rbx+32] 000af ff 15 00 00 00 00 call QWORD PTR __imp_realloc 000b5 48 8b c8 mov rcx, rax ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); 000b8 48 85 c0 test rax, rax 000bb 75 35 jne SHORT $LN7@stbi__zexp ; 431 : stbi__g_failure_reason = str; 000bd 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000c3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000cc 48 8b 74 24 30 mov rsi, QWORD PTR [rsp+48] 000d1 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000d6 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000da 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 000e1 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); 000e5 33 c0 xor eax, eax ; 3772 : } 000e7 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 000ec 48 83 c4 20 add rsp, 32 ; 00000020H 000f0 5f pop rdi 000f1 c3 ret 0 $LN7@stbi__zexp: ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; 000f2 8b c7 mov eax, edi 000f4 48 03 c1 add rax, rcx 000f7 48 89 4b 20 mov QWORD PTR [rbx+32], rcx 000fb 48 89 43 18 mov QWORD PTR [rbx+24], rax ; 3770 : z->zout_end = q + limit; 000ff 48 8d 04 0e lea rax, QWORD PTR [rsi+rcx] 00103 48 8b 74 24 30 mov rsi, QWORD PTR [rsp+48] 00108 48 89 43 28 mov QWORD PTR [rbx+40], rax ; 3771 : return 1; 0010c b8 01 00 00 00 mov eax, 1 ; 3772 : } 00111 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 00116 48 83 c4 20 add rsp, 32 ; 00000020H 0011a 5f pop rdi 0011b c3 ret 0 stbi__zexpand ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_huffman_block _TEXT SEGMENT a$ = 64 stbi__parse_huffman_block PROC ; COMDAT ; 3789 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 0000a 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi 0000f 57 push rdi 00010 41 54 push r12 00012 41 57 push r15 00014 48 83 ec 20 sub rsp, 32 ; 00000020H ; 3790 : char* zout = a->zout; 00018 48 8b 71 18 mov rsi, QWORD PTR [rcx+24] ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0001c 4c 8d 25 00 00 00 00 lea r12, OFFSET FLAT:__ImageBase ; 3789 : { 00023 48 8b d9 mov rbx, rcx ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00026 4c 89 74 24 40 mov QWORD PTR [rsp+64], r14 0002b 0f 1f 44 00 00 npad 5 $LL2@stbi__pars: ; 3736 : if (a->num_bits < 16) { 00030 44 8b 43 10 mov r8d, DWORD PTR [rbx+16] 00034 41 83 f8 10 cmp r8d, 16 00038 7d 64 jge SHORT $LN39@stbi__pars ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0003a 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 0003e 48 8b 13 mov rdx, QWORD PTR [rbx] 00041 49 3b d2 cmp rdx, r10 ; 3737 : if (stbi__zeof(a)) { 00044 0f 83 6c 03 00 00 jae $LN165@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0004a 44 8b 4b 14 mov r9d, DWORD PTR [rbx+20] ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); 0004e 41 8b c8 mov ecx, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00051 b8 01 00 00 00 mov eax, 1 00056 d3 e0 shl eax, cl 00058 44 3b c8 cmp r9d, eax 0005b 73 3e jae SHORT $LN113@stbi__pars 0005d 0f 1f 00 npad 3 $LL40@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00060 49 3b d2 cmp rdx, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00063 72 04 jb SHORT $LN45@stbi__pars 00065 32 c0 xor al, al 00067 eb 09 jmp SHORT $LN46@stbi__pars $LN45@stbi__pars: 00069 0f b6 02 movzx eax, BYTE PTR [rdx] 0006c 48 ff c2 inc rdx 0006f 48 89 13 mov QWORD PTR [rbx], rdx $LN46@stbi__pars: ; 3700 : z->num_bits += 8; 00072 44 8d 41 08 lea r8d, DWORD PTR [rcx+8] 00076 0f b6 c0 movzx eax, al 00079 d3 e0 shl eax, cl 0007b 44 0b c8 or r9d, eax 0007e 44 89 43 10 mov DWORD PTR [rbx+16], r8d 00082 44 89 4b 14 mov DWORD PTR [rbx+20], r9d ; 3701 : } while (z->num_bits <= 24); 00086 41 83 f8 18 cmp r8d, 24 0008a 7f 12 jg SHORT $LN39@stbi__pars 0008c 41 8b c8 mov ecx, r8d 0008f b8 01 00 00 00 mov eax, 1 00094 d3 e0 shl eax, cl 00096 44 3b c8 cmp r9d, eax 00099 72 c5 jb SHORT $LL40@stbi__pars $LN113@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0009b 4c 89 13 mov QWORD PTR [rbx], r10 $LN39@stbi__pars: ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; 0009e 8b 53 14 mov edx, DWORD PTR [rbx+20] 000a1 8b c2 mov eax, edx 000a3 25 ff 01 00 00 and eax, 511 ; 000001ffH 000a8 0f b7 7c 43 34 movzx edi, WORD PTR [rbx+rax*2+52] ; 3743 : if (b) { 000ad 85 ff test edi, edi 000af 74 19 je SHORT $LN33@stbi__pars ; 3744 : s = b >> 9; 000b1 8b cf mov ecx, edi 000b3 c1 e9 09 shr ecx, 9 ; 3745 : a->code_buffer >>= s; 000b6 d3 ea shr edx, cl ; 3746 : a->num_bits -= s; 000b8 44 2b c1 sub r8d, ecx 000bb 89 53 14 mov DWORD PTR [rbx+20], edx ; 3747 : return b & 511; 000be 81 e7 ff 01 00 00 and edi, 511 ; 000001ffH 000c4 44 89 43 10 mov DWORD PTR [rbx+16], r8d 000c8 eb 0e jmp SHORT $LN30@stbi__pars $LN33@stbi__pars: ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); 000ca 48 8d 53 34 lea rdx, QWORD PTR [rbx+52] 000ce 48 8b cb mov rcx, rbx 000d1 e8 00 00 00 00 call stbi__zhuffman_decode_slowpath 000d6 8b f8 mov edi, eax $LN30@stbi__pars: ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { 000d8 81 ff 00 01 00 00 cmp edi, 256 ; 00000100H 000de 7d 36 jge SHORT $LN11@stbi__pars ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes 000e0 85 ff test edi, edi 000e2 0f 88 ce 02 00 00 js $LN165@stbi__pars ; 3795 : if (zout >= a->zout_end) { 000e8 48 3b 73 28 cmp rsi, QWORD PTR [rbx+40] 000ec 72 1d jb SHORT $LN14@stbi__pars ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; 000ee 41 b8 01 00 00 00 mov r8d, 1 000f4 48 8b d6 mov rdx, rsi 000f7 48 8b cb mov rcx, rbx 000fa e8 00 00 00 00 call stbi__zexpand 000ff 85 c0 test eax, eax 00101 0f 84 d2 02 00 00 je $LN123@stbi__pars ; 3797 : zout = a->zout; 00107 48 8b 73 18 mov rsi, QWORD PTR [rbx+24] $LN14@stbi__pars: ; 3798 : } ; 3799 : *zout++ = (char)z; 0010b 40 88 3e mov BYTE PTR [rsi], dil 0010e 48 ff c6 inc rsi ; 3800 : } 00111 e9 1a ff ff ff jmp $LL2@stbi__pars $LN11@stbi__pars: ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { 00116 0f 84 e8 02 00 00 je $LN119@stbi__pars ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data 0011c 81 ff 1e 01 00 00 cmp edi, 286 ; 0000011eH 00122 0f 8d 8e 02 00 00 jge $LN165@stbi__pars ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; 00128 48 63 c7 movsxd rax, edi ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); 0012b 41 8b bc 84 fc fb ff ff mov edi, DWORD PTR stbi__zlength_extra[r12+rax*4-1028] 00133 41 8b ac 84 fc fb ff ff mov ebp, DWORD PTR stbi__zlength_base[r12+rax*4-1028] 0013b 85 ff test edi, edi 0013d 0f 84 92 00 00 00 je $LN163@stbi__pars ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00143 44 8b 43 10 mov r8d, DWORD PTR [rbx+16] 00147 44 3b c7 cmp r8d, edi 0014a 7d 69 jge SHORT $LN58@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0014c 8b 53 14 mov edx, DWORD PTR [rbx+20] 0014f 41 8b c8 mov ecx, r8d 00152 b8 01 00 00 00 mov eax, 1 ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); 00157 45 8b d0 mov r10d, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0015a d3 e0 shl eax, cl 0015c 45 8b c8 mov r9d, r8d 0015f 3b d0 cmp edx, eax 00161 73 48 jae SHORT $LN114@stbi__pars 00163 4c 8b 5b 08 mov r11, QWORD PTR [rbx+8] $LL59@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00167 48 8b 03 mov rax, QWORD PTR [rbx] 0016a 49 3b c3 cmp rax, r11 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0016d 72 04 jb SHORT $LN64@stbi__pars 0016f 32 c9 xor cl, cl 00171 eb 09 jmp SHORT $LN65@stbi__pars $LN64@stbi__pars: 00173 0f b6 08 movzx ecx, BYTE PTR [rax] 00176 48 ff c0 inc rax 00179 48 89 03 mov QWORD PTR [rbx], rax $LN65@stbi__pars: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 0017c 0f b6 c1 movzx eax, cl ; 3700 : z->num_bits += 8; 0017f 45 8d 42 08 lea r8d, DWORD PTR [r10+8] 00183 41 8b ca mov ecx, r10d 00186 44 89 43 10 mov DWORD PTR [rbx+16], r8d 0018a d3 e0 shl eax, cl 0018c 0b d0 or edx, eax 0018e 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 00191 41 83 f8 18 cmp r8d, 24 00195 7f 1e jg SHORT $LN58@stbi__pars ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00197 41 8b c8 mov ecx, r8d 0019a b8 01 00 00 00 mov eax, 1 0019f d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 001a1 45 8b d0 mov r10d, r8d 001a4 45 8b c8 mov r9d, r8d 001a7 3b d0 cmp edx, eax 001a9 72 bc jb SHORT $LL59@stbi__pars $LN114@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 001ab 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 001af 45 8b c1 mov r8d, r9d 001b2 48 89 03 mov QWORD PTR [rbx], rax $LN58@stbi__pars: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 001b5 8b 53 14 mov edx, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; 001b8 8b cf mov ecx, edi ; 3710 : z->num_bits -= n; 001ba 44 2b c7 sub r8d, edi 001bd 8b c2 mov eax, edx 001bf d3 e8 shr eax, cl 001c1 89 43 14 mov DWORD PTR [rbx+20], eax 001c4 b8 01 00 00 00 mov eax, 1 001c9 d3 e0 shl eax, cl 001cb ff c8 dec eax 001cd 44 89 43 10 mov DWORD PTR [rbx+16], r8d 001d1 23 c2 and eax, edx ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); 001d3 03 e8 add ebp, eax $LN163@stbi__pars: ; 3736 : if (a->num_bits < 16) { 001d5 44 8b 43 10 mov r8d, DWORD PTR [rbx+16] 001d9 41 83 f8 10 cmp r8d, 16 001dd 7d 61 jge SHORT $LN77@stbi__pars ; 3684 : return (z->zbuffer >= z->zbuffer_end); 001df 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 001e3 48 8b 13 mov rdx, QWORD PTR [rbx] 001e6 49 3b d2 cmp rdx, r10 ; 3737 : if (stbi__zeof(a)) { 001e9 0f 83 c7 01 00 00 jae $LN165@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 001ef 44 8b 4b 14 mov r9d, DWORD PTR [rbx+20] ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); 001f3 41 8b c8 mov ecx, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 001f6 b8 01 00 00 00 mov eax, 1 001fb d3 e0 shl eax, cl 001fd 44 3b c8 cmp r9d, eax 00200 73 3b jae SHORT $LN115@stbi__pars $LL78@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00202 49 3b d2 cmp rdx, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00205 72 04 jb SHORT $LN83@stbi__pars 00207 32 c0 xor al, al 00209 eb 09 jmp SHORT $LN84@stbi__pars $LN83@stbi__pars: 0020b 0f b6 02 movzx eax, BYTE PTR [rdx] 0020e 48 ff c2 inc rdx 00211 48 89 13 mov QWORD PTR [rbx], rdx $LN84@stbi__pars: ; 3700 : z->num_bits += 8; 00214 44 8d 41 08 lea r8d, DWORD PTR [rcx+8] 00218 0f b6 c0 movzx eax, al 0021b d3 e0 shl eax, cl 0021d 44 0b c8 or r9d, eax 00220 44 89 43 10 mov DWORD PTR [rbx+16], r8d 00224 44 89 4b 14 mov DWORD PTR [rbx+20], r9d ; 3701 : } while (z->num_bits <= 24); 00228 41 83 f8 18 cmp r8d, 24 0022c 7f 12 jg SHORT $LN77@stbi__pars 0022e 41 8b c8 mov ecx, r8d 00231 b8 01 00 00 00 mov eax, 1 00236 d3 e0 shl eax, cl 00238 44 3b c8 cmp r9d, eax 0023b 72 c5 jb SHORT $LL78@stbi__pars $LN115@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0023d 4c 89 13 mov QWORD PTR [rbx], r10 $LN77@stbi__pars: ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; 00240 8b 53 14 mov edx, DWORD PTR [rbx+20] 00243 8b c2 mov eax, edx 00245 25 ff 01 00 00 and eax, 511 ; 000001ffH 0024a 0f b7 84 43 18 08 00 00 movzx eax, WORD PTR [rbx+rax*2+2072] ; 3743 : if (b) { 00252 85 c0 test eax, eax 00254 74 18 je SHORT $LN71@stbi__pars ; 3744 : s = b >> 9; 00256 8b c8 mov ecx, eax 00258 c1 e9 09 shr ecx, 9 ; 3745 : a->code_buffer >>= s; 0025b d3 ea shr edx, cl ; 3746 : a->num_bits -= s; 0025d 44 2b c1 sub r8d, ecx 00260 89 53 14 mov DWORD PTR [rbx+20], edx ; 3747 : return b & 511; 00263 25 ff 01 00 00 and eax, 511 ; 000001ffH 00268 44 89 43 10 mov DWORD PTR [rbx+16], r8d 0026c eb 0f jmp SHORT $LN68@stbi__pars $LN71@stbi__pars: ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); 0026e 48 8d 93 18 08 00 00 lea rdx, QWORD PTR [rbx+2072] 00275 48 8b cb mov rcx, rbx 00278 e8 00 00 00 00 call stbi__zhuffman_decode_slowpath $LN68@stbi__pars: ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data 0027d 83 f8 1d cmp eax, 29 00280 0f 87 30 01 00 00 ja $LN165@stbi__pars ; 3814 : dist = stbi__zdist_base[z]; 00286 48 98 cdqe ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); 00288 45 8b 9c 84 00 00 00 00 mov r11d, DWORD PTR stbi__zdist_extra[r12+rax*4] 00290 45 8b b4 84 00 00 00 00 mov r14d, DWORD PTR stbi__zdist_base[r12+rax*4] 00298 45 85 db test r11d, r11d 0029b 0f 84 8b 00 00 00 je $LN162@stbi__pars ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 002a1 44 8b 43 10 mov r8d, DWORD PTR [rbx+16] 002a5 45 3b c3 cmp r8d, r11d 002a8 7d 60 jge SHORT $LN94@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 002aa 8b 53 14 mov edx, DWORD PTR [rbx+20] 002ad 41 8b c8 mov ecx, r8d 002b0 b8 01 00 00 00 mov eax, 1 ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); 002b5 45 8b c8 mov r9d, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 002b8 d3 e0 shl eax, cl 002ba 3b d0 cmp edx, eax 002bc 73 45 jae SHORT $LN116@stbi__pars 002be 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] $LL95@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 002c2 48 8b 03 mov rax, QWORD PTR [rbx] 002c5 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 002c8 72 04 jb SHORT $LN100@stbi__pars 002ca 32 c9 xor cl, cl 002cc eb 09 jmp SHORT $LN101@stbi__pars $LN100@stbi__pars: 002ce 0f b6 08 movzx ecx, BYTE PTR [rax] 002d1 48 ff c0 inc rax 002d4 48 89 03 mov QWORD PTR [rbx], rax $LN101@stbi__pars: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 002d7 0f b6 c1 movzx eax, cl ; 3700 : z->num_bits += 8; 002da 45 8d 41 08 lea r8d, DWORD PTR [r9+8] 002de 41 8b c9 mov ecx, r9d 002e1 44 89 43 10 mov DWORD PTR [rbx+16], r8d 002e5 d3 e0 shl eax, cl 002e7 0b d0 or edx, eax 002e9 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 002ec 41 83 f8 18 cmp r8d, 24 002f0 7f 18 jg SHORT $LN94@stbi__pars ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 002f2 41 8b c8 mov ecx, r8d 002f5 b8 01 00 00 00 mov eax, 1 002fa d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 002fc 45 8b c8 mov r9d, r8d 002ff 3b d0 cmp edx, eax 00301 72 bf jb SHORT $LL95@stbi__pars $LN116@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00303 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 00307 48 89 03 mov QWORD PTR [rbx], rax $LN94@stbi__pars: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 0030a 8b 53 14 mov edx, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; 0030d 41 8b cb mov ecx, r11d ; 3710 : z->num_bits -= n; 00310 45 2b c3 sub r8d, r11d 00313 8b c2 mov eax, edx 00315 d3 e8 shr eax, cl 00317 89 43 14 mov DWORD PTR [rbx+20], eax 0031a b8 01 00 00 00 mov eax, 1 0031f d3 e0 shl eax, cl 00321 ff c8 dec eax 00323 44 89 43 10 mov DWORD PTR [rbx+16], r8d 00327 23 c2 and eax, edx ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); 00329 44 03 f0 add r14d, eax $LN162@stbi__pars: ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); 0032c 48 8b c6 mov rax, rsi 0032f 49 63 fe movsxd rdi, r14d 00332 48 2b 43 20 sub rax, QWORD PTR [rbx+32] 00336 48 3b c7 cmp rax, rdi 00339 0f 8c 9e 00 00 00 jl $LN122@stbi__pars ; 3817 : if (zout + len > a->zout_end) { 0033f 48 63 c5 movsxd rax, ebp 00342 48 03 c6 add rax, rsi 00345 48 3b 43 28 cmp rax, QWORD PTR [rbx+40] 00349 76 16 jbe SHORT $LN23@stbi__pars ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; 0034b 44 8b c5 mov r8d, ebp 0034e 48 8b d6 mov rdx, rsi 00351 48 8b cb mov rcx, rbx 00354 e8 00 00 00 00 call stbi__zexpand 00359 85 c0 test eax, eax 0035b 74 7c je SHORT $LN123@stbi__pars ; 3819 : zout = a->zout; 0035d 48 8b 73 18 mov rsi, QWORD PTR [rbx+24] $LN23@stbi__pars: ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); 00361 48 8b ce mov rcx, rsi 00364 48 2b cf sub rcx, rdi ; 3822 : if (dist == 1) { // run of one byte; common in images. 00367 41 83 fe 01 cmp r14d, 1 0036b 75 20 jne SHORT $LN25@stbi__pars ; 3824 : if (len) { do *zout++ = v; while (--len); } 0036d 85 ed test ebp, ebp 0036f 0f 84 bb fc ff ff je $LL2@stbi__pars ; 3823 : stbi_uc v = *p; 00375 0f b6 11 movzx edx, BYTE PTR [rcx] 00378 48 8b ce mov rcx, rsi 0037b 44 8b c5 mov r8d, ebp 0037e 8b fd mov edi, ebp 00380 e8 00 00 00 00 call memset 00385 48 03 f7 add rsi, rdi ; 3825 : } 00388 e9 a3 fc ff ff jmp $LL2@stbi__pars $LN25@stbi__pars: ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } 0038d 85 ed test ebp, ebp 0038f 0f 84 9b fc ff ff je $LL2@stbi__pars 00395 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL10@stbi__pars: 003a0 0f b6 01 movzx eax, BYTE PTR [rcx] 003a3 48 8d 49 01 lea rcx, QWORD PTR [rcx+1] 003a7 88 06 mov BYTE PTR [rsi], al 003a9 48 ff c6 inc rsi 003ac 83 ed 01 sub ebp, 1 003af 75 ef jne SHORT $LL10@stbi__pars ; 3828 : } ; 3829 : } ; 3830 : } 003b1 e9 7a fc ff ff jmp $LL2@stbi__pars $LN165@stbi__pars: ; 3831 : } 003b6 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 003bc 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 003c5 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 003ca 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 003ce 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@IIMLINA@bad?5huffman?5code@ 003d5 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN123@stbi__pars: 003d9 33 c0 xor eax, eax 003db eb 30 jmp SHORT $LN3@stbi__pars $LN122@stbi__pars: ; 431 : stbi__g_failure_reason = str; 003dd 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 003e3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 003ec b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 003f1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 003f5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08DIAPIMGJ@bad?5dist@ 003fc 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); 00400 33 c0 xor eax, eax 00402 eb 09 jmp SHORT $LN3@stbi__pars $LN119@stbi__pars: ; 3805 : a->zout = zout; 00404 48 89 73 18 mov QWORD PTR [rbx+24], rsi ; 3806 : return 1; 00408 b8 01 00 00 00 mov eax, 1 $LN3@stbi__pars: ; 3831 : } 0040d 4c 8b 74 24 40 mov r14, QWORD PTR [rsp+64] 00412 48 8b 5c 24 48 mov rbx, QWORD PTR [rsp+72] 00417 48 8b 6c 24 50 mov rbp, QWORD PTR [rsp+80] 0041c 48 8b 74 24 58 mov rsi, QWORD PTR [rsp+88] 00421 48 83 c4 20 add rsp, 32 ; 00000020H 00425 41 5f pop r15 00427 41 5c pop r12 00429 5f pop rdi 0042a c3 ret 0 stbi__parse_huffman_block ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__compute_huffman_codes _TEXT SEGMENT ntot$1$ = 32 hlit$1$ = 36 z_codelength$ = 48 codelength_sizes$ = 2080 lencodes$ = 2112 __$ArrayPad$ = 2576 a$ = 2640 stbi__compute_huffman_codes PROC ; COMDAT ; 3834 : { 00000 40 53 push rbx 00002 55 push rbp 00003 41 54 push r12 00005 41 55 push r13 00007 41 57 push r15 00009 48 81 ec 20 0a 00 00 sub rsp, 2592 ; 00000a20H 00010 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00017 48 33 c4 xor rax, rsp 0001a 48 89 84 24 10 0a 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00022 48 8b d9 mov rbx, rcx 00025 4c 89 b4 24 68 0a 00 00 mov QWORD PTR [rsp+2664], r14 ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 0002d 8b 49 10 mov ecx, DWORD PTR [rcx+16] 00030 83 f9 05 cmp ecx, 5 00033 7d 64 jge SHORT $LN108@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00035 8b 53 14 mov edx, DWORD PTR [rbx+20] 00038 b8 01 00 00 00 mov eax, 1 0003d d3 e0 shl eax, cl ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0003f 44 8b c1 mov r8d, ecx ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00042 44 8b c9 mov r9d, ecx 00045 3b d0 cmp edx, eax 00047 73 46 jae SHORT $LN168@stbi__comp 00049 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 0004d 0f 1f 00 npad 3 $LL109@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00050 48 8b 03 mov rax, QWORD PTR [rbx] 00053 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00056 72 04 jb SHORT $LN114@stbi__comp 00058 32 c9 xor cl, cl 0005a eb 09 jmp SHORT $LN115@stbi__comp $LN114@stbi__comp: 0005c 0f b6 08 movzx ecx, BYTE PTR [rax] 0005f 48 ff c0 inc rax 00062 48 89 03 mov QWORD PTR [rbx], rax $LN115@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00065 0f b6 c1 movzx eax, cl 00068 41 8b c8 mov ecx, r8d 0006b d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 0006d 41 8d 48 08 lea ecx, DWORD PTR [r8+8] 00071 0b d0 or edx, eax 00073 89 4b 10 mov DWORD PTR [rbx+16], ecx 00076 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 00079 83 f9 18 cmp ecx, 24 0007c 7f 1b jg SHORT $LN108@stbi__comp 0007e b8 01 00 00 00 mov eax, 1 00083 44 8b c1 mov r8d, ecx 00086 d3 e0 shl eax, cl 00088 44 8b c9 mov r9d, ecx 0008b 3b d0 cmp edx, eax 0008d 72 c1 jb SHORT $LL109@stbi__comp $LN168@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0008f 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 00093 41 8b c9 mov ecx, r9d 00096 48 89 03 mov QWORD PTR [rbx], rax $LN108@stbi__comp: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 00099 8b 43 14 mov eax, DWORD PTR [rbx+20] ; 3710 : z->num_bits -= n; 0009c 8d 51 fb lea edx, DWORD PTR [rcx-5] 0009f 44 8b f8 mov r15d, eax 000a2 89 53 10 mov DWORD PTR [rbx+16], edx 000a5 83 e0 1f and eax, 31 000a8 41 c1 ef 05 shr r15d, 5 000ac 44 89 7b 14 mov DWORD PTR [rbx+20], r15d ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; 000b0 8d a8 01 01 00 00 lea ebp, DWORD PTR [rax+257] 000b6 89 6c 24 24 mov DWORD PTR hlit$1$[rsp], ebp ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 000ba 83 fa 05 cmp edx, 5 000bd 7d 74 jge SHORT $LN123@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 000bf 8b ca mov ecx, edx 000c1 b8 01 00 00 00 mov eax, 1 000c6 d3 e0 shl eax, cl ; 3684 : return (z->zbuffer >= z->zbuffer_end); 000c8 45 8b c7 mov r8d, r15d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 000cb 44 8b ca mov r9d, edx 000ce 44 8b d2 mov r10d, edx 000d1 44 3b f8 cmp r15d, eax 000d4 73 53 jae SHORT $LN169@stbi__comp 000d6 4c 8b 5b 08 mov r11, QWORD PTR [rbx+8] 000da 66 0f 1f 44 00 00 npad 6 $LL124@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 000e0 48 8b 03 mov rax, QWORD PTR [rbx] 000e3 49 3b c3 cmp rax, r11 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 000e6 72 04 jb SHORT $LN129@stbi__comp 000e8 32 c9 xor cl, cl 000ea eb 09 jmp SHORT $LN130@stbi__comp $LN129@stbi__comp: 000ec 0f b6 08 movzx ecx, BYTE PTR [rax] 000ef 48 ff c0 inc rax 000f2 48 89 03 mov QWORD PTR [rbx], rax $LN130@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 000f5 44 0f b6 f9 movzx r15d, cl ; 3700 : z->num_bits += 8; 000f9 41 8d 52 08 lea edx, DWORD PTR [r10+8] 000fd 41 8b c9 mov ecx, r9d 00100 89 53 10 mov DWORD PTR [rbx+16], edx 00103 41 d3 e7 shl r15d, cl 00106 45 0b f8 or r15d, r8d 00109 44 89 7b 14 mov DWORD PTR [rbx+20], r15d ; 3701 : } while (z->num_bits <= 24); 0010d 83 fa 18 cmp edx, 24 00110 7f 21 jg SHORT $LN123@stbi__comp ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00112 8b ca mov ecx, edx 00114 b8 01 00 00 00 mov eax, 1 00119 d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 0011b 45 8b c7 mov r8d, r15d 0011e 44 8b ca mov r9d, edx 00121 44 8b d2 mov r10d, edx 00124 44 3b f8 cmp r15d, eax 00127 72 b7 jb SHORT $LL124@stbi__comp $LN169@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00129 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 0012d 45 8b f8 mov r15d, r8d 00130 48 89 03 mov QWORD PTR [rbx], rax $LN123@stbi__comp: ; 3709 : z->code_buffer >>= n; 00133 45 8b c7 mov r8d, r15d 00136 48 89 bc 24 60 0a 00 00 mov QWORD PTR [rsp+2656], rdi ; 3708 : k = z->code_buffer & ((1 << n) - 1); 0013e 41 83 e7 1f and r15d, 31 ; 3709 : z->code_buffer >>= n; 00142 41 c1 e8 05 shr r8d, 5 ; 3710 : z->num_bits -= n; 00146 83 c2 fb add edx, -5 00149 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; 0014d 41 ff c7 inc r15d ; 3710 : z->num_bits -= n; 00150 89 53 10 mov DWORD PTR [rbx+16], edx ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00153 83 fa 04 cmp edx, 4 00156 7d 6e jge SHORT $LN138@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00158 8b ca mov ecx, edx 0015a b8 01 00 00 00 mov eax, 1 0015f d3 e0 shl eax, cl ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00161 45 8b c8 mov r9d, r8d ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00164 44 8b d2 mov r10d, edx 00167 44 8b da mov r11d, edx 0016a 44 3b c0 cmp r8d, eax 0016d 73 4d jae SHORT $LN170@stbi__comp 0016f 48 8b 7b 08 mov rdi, QWORD PTR [rbx+8] $LL139@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00173 48 8b 03 mov rax, QWORD PTR [rbx] 00176 48 3b c7 cmp rax, rdi ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00179 72 04 jb SHORT $LN144@stbi__comp 0017b 32 c9 xor cl, cl 0017d eb 09 jmp SHORT $LN145@stbi__comp $LN144@stbi__comp: 0017f 0f b6 08 movzx ecx, BYTE PTR [rax] 00182 48 ff c0 inc rax 00185 48 89 03 mov QWORD PTR [rbx], rax $LN145@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00188 44 0f b6 c1 movzx r8d, cl ; 3700 : z->num_bits += 8; 0018c 41 8d 53 08 lea edx, DWORD PTR [r11+8] 00190 41 8b ca mov ecx, r10d 00193 89 53 10 mov DWORD PTR [rbx+16], edx 00196 41 d3 e0 shl r8d, cl 00199 45 0b c1 or r8d, r9d 0019c 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3701 : } while (z->num_bits <= 24); 001a0 83 fa 18 cmp edx, 24 001a3 7f 21 jg SHORT $LN138@stbi__comp ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 001a5 8b ca mov ecx, edx 001a7 b8 01 00 00 00 mov eax, 1 001ac d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 001ae 45 8b c8 mov r9d, r8d 001b1 44 8b d2 mov r10d, edx 001b4 44 8b da mov r11d, edx 001b7 44 3b c0 cmp r8d, eax 001ba 72 b7 jb SHORT $LL139@stbi__comp $LN170@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 001bc 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 001c0 45 8b c1 mov r8d, r9d 001c3 48 89 03 mov QWORD PTR [rbx], rax $LN138@stbi__comp: ; 3709 : z->code_buffer >>= n; 001c6 45 8b c8 mov r9d, r8d 001c9 48 89 b4 24 58 0a 00 00 mov QWORD PTR [rsp+2648], rsi ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); 001d1 33 c0 xor eax, eax ; 3709 : z->code_buffer >>= n; 001d3 41 c1 e9 04 shr r9d, 4 001d7 41 83 e0 0f and r8d, 15 001db 44 89 4b 14 mov DWORD PTR [rbx+20], r9d ; 3847 : for (i = 0; i < hclen; ++i) { 001df 45 33 ed xor r13d, r13d 001e2 66 89 84 24 30 08 00 00 mov WORD PTR codelength_sizes$[rsp+16], ax 001ea 41 83 c0 04 add r8d, 4 001ee 88 84 24 32 08 00 00 mov BYTE PTR codelength_sizes$[rsp+18], al ; 3710 : z->num_bits -= n; 001f5 44 8d 52 fc lea r10d, DWORD PTR [rdx-4] ; 3847 : for (i = 0; i < hclen; ++i) { 001f9 45 8b f0 mov r14d, r8d 001fc 45 8d 24 2f lea r12d, DWORD PTR [r15+rbp] ; 3710 : z->num_bits -= n; 00200 44 89 53 10 mov DWORD PTR [rbx+16], r10d 00204 0f 57 c0 xorps xmm0, xmm0 ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; 00207 44 89 64 24 20 mov DWORD PTR ntot$1$[rsp], r12d ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); 0020c 0f 11 84 24 20 08 00 00 movups XMMWORD PTR codelength_sizes$[rsp], xmm0 ; 3847 : for (i = 0; i < hclen; ++i) { 00214 0f 84 c3 00 00 00 je $LN216@stbi__comp ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0021a 41 8b ed mov ebp, r13d 0021d 4c 8d 25 00 00 00 00 lea r12, OFFSET FLAT:?length_dezigzag@?1??stbi__compute_huffman_codes@@9@9 00224 45 8b c2 mov r8d, r10d $LL4@stbi__comp: ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00227 41 8b d1 mov edx, r9d 0022a 41 83 fa 03 cmp r10d, 3 0022e 7d 73 jge SHORT $LN63@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00230 41 8b ca mov ecx, r10d 00233 b8 01 00 00 00 mov eax, 1 00238 d3 e0 shl eax, cl 0023a 41 8b f9 mov edi, r9d 0023d 45 8b da mov r11d, r10d 00240 44 3b c8 cmp r9d, eax 00243 73 54 jae SHORT $LN171@stbi__comp 00245 48 8b 73 08 mov rsi, QWORD PTR [rbx+8] 00249 0f 1f 80 00 00 00 00 npad 7 $LL64@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00250 48 8b 03 mov rax, QWORD PTR [rbx] 00253 48 3b c6 cmp rax, rsi ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00256 72 04 jb SHORT $LN69@stbi__comp 00258 32 c9 xor cl, cl 0025a eb 09 jmp SHORT $LN70@stbi__comp $LN69@stbi__comp: 0025c 0f b6 08 movzx ecx, BYTE PTR [rax] 0025f 48 ff c0 inc rax 00262 48 89 03 mov QWORD PTR [rbx], rax $LN70@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00265 0f b6 d1 movzx edx, cl ; 3700 : z->num_bits += 8; 00268 45 8d 42 08 lea r8d, DWORD PTR [r10+8] 0026c 41 8b cb mov ecx, r11d 0026f 44 89 43 10 mov DWORD PTR [rbx+16], r8d 00273 d3 e2 shl edx, cl 00275 0b d7 or edx, edi 00277 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 0027a 41 83 f8 18 cmp r8d, 24 0027e 7f 23 jg SHORT $LN63@stbi__comp ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00280 41 8b c8 mov ecx, r8d 00283 b8 01 00 00 00 mov eax, 1 00288 d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 0028a 45 8b d8 mov r11d, r8d 0028d 44 8b ca mov r9d, edx 00290 45 8b d0 mov r10d, r8d 00293 8b fa mov edi, edx 00295 3b d0 cmp edx, eax 00297 72 b7 jb SHORT $LL64@stbi__comp $LN171@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00299 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 0029d 41 8b d1 mov edx, r9d 002a0 48 89 03 mov QWORD PTR [rbx], rax $LN63@stbi__comp: ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; 002a3 41 0f b6 04 2c movzx eax, BYTE PTR [r12+rbp] ; 3710 : z->num_bits -= n; 002a8 41 83 e8 03 sub r8d, 3 002ac 44 8b ca mov r9d, edx 002af 44 89 43 10 mov DWORD PTR [rbx+16], r8d 002b3 41 c1 e9 03 shr r9d, 3 002b7 80 e2 07 and dl, 7 ; 3847 : for (i = 0; i < hclen; ++i) { 002ba 48 ff c5 inc rbp ; 3709 : z->code_buffer >>= n; 002bd 44 89 4b 14 mov DWORD PTR [rbx+20], r9d ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; 002c1 88 94 04 20 08 00 00 mov BYTE PTR codelength_sizes$[rsp+rax], dl ; 3710 : z->num_bits -= n; 002c8 45 8b d0 mov r10d, r8d ; 3847 : for (i = 0; i < hclen; ++i) { 002cb 49 3b ee cmp rbp, r14 002ce 0f 8c 53 ff ff ff jl $LL4@stbi__comp 002d4 44 8b 64 24 20 mov r12d, DWORD PTR ntot$1$[rsp] 002d9 8b 6c 24 24 mov ebp, DWORD PTR hlit$1$[rsp] $LN216@stbi__comp: ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; 002dd 41 b8 13 00 00 00 mov r8d, 19 002e3 48 8d 94 24 20 08 00 00 lea rdx, QWORD PTR codelength_sizes$[rsp] 002eb 48 8d 4c 24 30 lea rcx, QWORD PTR z_codelength$[rsp] 002f0 e8 00 00 00 00 call stbi__zbuild_huffman 002f5 4c 8b b4 24 68 0a 00 00 mov r14, QWORD PTR [rsp+2664] 002fd 85 c0 test eax, eax 002ff 0f 84 2e 03 00 00 je $LN218@stbi__comp ; 3852 : ; 3853 : n = 0; 00305 41 8b f5 mov esi, r13d 00308 0f 1f 84 00 00 00 00 00 npad 8 $LL5@stbi__comp: ; 3736 : if (a->num_bits < 16) { 00310 44 8b 43 10 mov r8d, DWORD PTR [rbx+16] 00314 41 83 f8 10 cmp r8d, 16 00318 7d 67 jge SHORT $LN33@stbi__comp ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0031a 48 8b 13 mov rdx, QWORD PTR [rbx] 0031d 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 00321 49 3b d2 cmp rdx, r10 ; 3737 : if (stbi__zeof(a)) { 00324 0f 83 e6 02 00 00 jae $LN9@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0032a 44 8b 4b 14 mov r9d, DWORD PTR [rbx+20] 0032e 41 8b c8 mov ecx, r8d 00331 b8 01 00 00 00 mov eax, 1 00336 d3 e0 shl eax, cl 00338 44 3b c8 cmp r9d, eax 0033b 73 41 jae SHORT $LN217@stbi__comp 0033d 0f 1f 00 npad 3 $LL34@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00340 49 3b d2 cmp rdx, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00343 72 04 jb SHORT $LN39@stbi__comp 00345 32 c0 xor al, al 00347 eb 09 jmp SHORT $LN40@stbi__comp $LN39@stbi__comp: 00349 0f b6 02 movzx eax, BYTE PTR [rdx] 0034c 48 ff c2 inc rdx 0034f 48 89 13 mov QWORD PTR [rbx], rdx $LN40@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00352 41 8b c8 mov ecx, r8d 00355 0f b6 c0 movzx eax, al 00358 d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 0035a 41 83 c0 08 add r8d, 8 0035e 44 0b c8 or r9d, eax 00361 44 89 43 10 mov DWORD PTR [rbx+16], r8d 00365 44 89 4b 14 mov DWORD PTR [rbx+20], r9d ; 3701 : } while (z->num_bits <= 24); 00369 41 83 f8 18 cmp r8d, 24 0036d 7f 12 jg SHORT $LN33@stbi__comp ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0036f 41 8b c8 mov ecx, r8d 00372 b8 01 00 00 00 mov eax, 1 00377 d3 e0 shl eax, cl 00379 44 3b c8 cmp r9d, eax 0037c 72 c2 jb SHORT $LL34@stbi__comp $LN217@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0037e 4c 89 13 mov QWORD PTR [rbx], r10 $LN33@stbi__comp: ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; 00381 8b 53 14 mov edx, DWORD PTR [rbx+20] 00384 8b c2 mov eax, edx 00386 25 ff 01 00 00 and eax, 511 ; 000001ffH 0038b 0f b7 44 44 30 movzx eax, WORD PTR z_codelength$[rsp+rax*2] ; 3743 : if (b) { 00390 85 c0 test eax, eax 00392 74 18 je SHORT $LN27@stbi__comp ; 3744 : s = b >> 9; 00394 8b c8 mov ecx, eax 00396 c1 e9 09 shr ecx, 9 ; 3745 : a->code_buffer >>= s; 00399 d3 ea shr edx, cl ; 3746 : a->num_bits -= s; 0039b 44 2b c1 sub r8d, ecx 0039e 89 53 14 mov DWORD PTR [rbx+20], edx ; 3747 : return b & 511; 003a1 25 ff 01 00 00 and eax, 511 ; 000001ffH 003a6 44 89 43 10 mov DWORD PTR [rbx+16], r8d 003aa eb 0d jmp SHORT $LN24@stbi__comp $LN27@stbi__comp: ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); 003ac 48 8d 54 24 30 lea rdx, QWORD PTR z_codelength$[rsp] 003b1 48 8b cb mov rcx, rbx 003b4 e8 00 00 00 00 call stbi__zhuffman_decode_slowpath $LN24@stbi__comp: ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); 003b9 83 f8 12 cmp eax, 18 003bc 0f 87 4e 02 00 00 ja $LN9@stbi__comp ; 3857 : if (c < 16) 003c2 83 f8 10 cmp eax, 16 003c5 7d 14 jge SHORT $LN10@stbi__comp ; 3858 : lencodes[n++] = (stbi_uc)c; 003c7 48 63 ce movsxd rcx, esi 003ca bf 01 00 00 00 mov edi, 1 003cf 88 84 0c 40 08 00 00 mov BYTE PTR lencodes$[rsp+rcx], al 003d6 e9 e9 01 00 00 jmp $LN11@stbi__comp $LN10@stbi__comp: ; 3859 : else { ; 3860 : stbi_uc fill = 0; 003db 45 32 db xor r11b, r11b ; 3861 : if (c == 16) { 003de 83 f8 10 cmp eax, 16 003e1 0f 85 99 00 00 00 jne $LN12@stbi__comp ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 003e7 8b 4b 10 mov ecx, DWORD PTR [rbx+16] 003ea 83 f9 02 cmp ecx, 2 003ed 7d 61 jge SHORT $LN48@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 003ef 8b 53 14 mov edx, DWORD PTR [rbx+20] 003f2 b8 01 00 00 00 mov eax, 1 003f7 d3 e0 shl eax, cl 003f9 44 8b c9 mov r9d, ecx 003fc 44 8b c1 mov r8d, ecx 003ff 3b d0 cmp edx, eax 00401 73 43 jae SHORT $LN173@stbi__comp 00403 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] $LL49@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00407 48 8b 03 mov rax, QWORD PTR [rbx] 0040a 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0040d 72 04 jb SHORT $LN54@stbi__comp 0040f 32 c9 xor cl, cl 00411 eb 09 jmp SHORT $LN55@stbi__comp $LN54@stbi__comp: 00413 0f b6 08 movzx ecx, BYTE PTR [rax] 00416 48 ff c0 inc rax 00419 48 89 03 mov QWORD PTR [rbx], rax $LN55@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 0041c 0f b6 c1 movzx eax, cl 0041f 41 8b c9 mov ecx, r9d 00422 d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 00424 41 8d 49 08 lea ecx, DWORD PTR [r9+8] 00428 0b d0 or edx, eax 0042a 89 4b 10 mov DWORD PTR [rbx+16], ecx 0042d 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 00430 83 f9 18 cmp ecx, 24 00433 7f 1b jg SHORT $LN48@stbi__comp 00435 b8 01 00 00 00 mov eax, 1 0043a 44 8b c9 mov r9d, ecx 0043d d3 e0 shl eax, cl 0043f 44 8b c1 mov r8d, ecx 00442 3b d0 cmp edx, eax 00444 72 c1 jb SHORT $LL49@stbi__comp $LN173@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00446 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 0044a 41 8b c8 mov ecx, r8d 0044d 48 89 03 mov QWORD PTR [rbx], rax $LN48@stbi__comp: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 00450 8b 7b 14 mov edi, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; 00453 8b c7 mov eax, edi 00455 c1 e8 02 shr eax, 2 00458 83 e7 03 and edi, 3 0045b 89 43 14 mov DWORD PTR [rbx+20], eax ; 3862 : c = stbi__zreceive(a, 2) + 3; 0045e 83 c7 03 add edi, 3 ; 3710 : z->num_bits -= n; 00461 8d 41 fe lea eax, DWORD PTR [rcx-2] 00464 89 43 10 mov DWORD PTR [rbx+16], eax ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); 00467 85 f6 test esi, esi 00469 0f 84 a1 01 00 00 je $LN9@stbi__comp ; 3864 : fill = lencodes[n - 1]; 0046f 48 63 c6 movsxd rax, esi 00472 44 0f b6 9c 04 3f 08 00 00 movzx r11d, BYTE PTR lencodes$[rsp+rax-1] ; 3865 : } 0047b e9 21 01 00 00 jmp $LN18@stbi__comp $LN12@stbi__comp: ; 3866 : else if (c == 17) { 00480 83 f8 11 cmp eax, 17 00483 0f 85 8a 00 00 00 jne $LN15@stbi__comp ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00489 8b 4b 10 mov ecx, DWORD PTR [rbx+16] 0048c 83 f9 03 cmp ecx, 3 0048f 7d 69 jge SHORT $LN78@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00491 44 8b 43 14 mov r8d, DWORD PTR [rbx+20] 00495 b8 01 00 00 00 mov eax, 1 0049a d3 e0 shl eax, cl 0049c 44 8b c9 mov r9d, ecx 0049f 8b d1 mov edx, ecx 004a1 44 3b c0 cmp r8d, eax 004a4 73 4b jae SHORT $LN174@stbi__comp 004a6 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 004aa 66 0f 1f 44 00 00 npad 6 $LL79@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 004b0 48 8b 03 mov rax, QWORD PTR [rbx] 004b3 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 004b6 72 04 jb SHORT $LN84@stbi__comp 004b8 32 c9 xor cl, cl 004ba eb 09 jmp SHORT $LN85@stbi__comp $LN84@stbi__comp: 004bc 0f b6 08 movzx ecx, BYTE PTR [rax] 004bf 48 ff c0 inc rax 004c2 48 89 03 mov QWORD PTR [rbx], rax $LN85@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 004c5 0f b6 c1 movzx eax, cl 004c8 41 8b c9 mov ecx, r9d 004cb d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 004cd 41 8d 49 08 lea ecx, DWORD PTR [r9+8] 004d1 44 0b c0 or r8d, eax 004d4 89 4b 10 mov DWORD PTR [rbx+16], ecx 004d7 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3701 : } while (z->num_bits <= 24); 004db 83 f9 18 cmp ecx, 24 004de 7f 1a jg SHORT $LN78@stbi__comp 004e0 b8 01 00 00 00 mov eax, 1 004e5 44 8b c9 mov r9d, ecx 004e8 d3 e0 shl eax, cl 004ea 8b d1 mov edx, ecx 004ec 44 3b c0 cmp r8d, eax 004ef 72 bf jb SHORT $LL79@stbi__comp $LN174@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 004f1 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 004f5 8b ca mov ecx, edx 004f7 48 89 03 mov QWORD PTR [rbx], rax $LN78@stbi__comp: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 004fa 8b 7b 14 mov edi, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; 004fd 8b c7 mov eax, edi 004ff c1 e8 03 shr eax, 3 00502 83 e7 07 and edi, 7 00505 89 43 14 mov DWORD PTR [rbx+20], eax ; 3867 : c = stbi__zreceive(a, 3) + 3; 00508 83 c7 03 add edi, 3 ; 3710 : z->num_bits -= n; 0050b 8d 41 fd lea eax, DWORD PTR [rcx-3] ; 3868 : } 0050e e9 8b 00 00 00 jmp $LN273@stbi__comp $LN15@stbi__comp: ; 3869 : else if (c == 18) { 00513 83 f8 12 cmp eax, 18 00516 0f 85 f4 00 00 00 jne $LN9@stbi__comp ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 0051c 8b 4b 10 mov ecx, DWORD PTR [rbx+16] 0051f 83 f9 07 cmp ecx, 7 00522 7d 66 jge SHORT $LN93@stbi__comp ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00524 44 8b 43 14 mov r8d, DWORD PTR [rbx+20] 00528 b8 01 00 00 00 mov eax, 1 0052d d3 e0 shl eax, cl 0052f 44 8b c9 mov r9d, ecx 00532 8b d1 mov edx, ecx 00534 44 3b c0 cmp r8d, eax 00537 73 48 jae SHORT $LN175@stbi__comp 00539 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] 0053d 0f 1f 00 npad 3 $LL94@stbi__comp: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00540 48 8b 03 mov rax, QWORD PTR [rbx] 00543 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00546 72 04 jb SHORT $LN99@stbi__comp 00548 32 c9 xor cl, cl 0054a eb 09 jmp SHORT $LN100@stbi__comp $LN99@stbi__comp: 0054c 0f b6 08 movzx ecx, BYTE PTR [rax] 0054f 48 ff c0 inc rax 00552 48 89 03 mov QWORD PTR [rbx], rax $LN100@stbi__comp: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00555 0f b6 c1 movzx eax, cl 00558 41 8b c9 mov ecx, r9d 0055b d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 0055d 41 8d 49 08 lea ecx, DWORD PTR [r9+8] 00561 44 0b c0 or r8d, eax 00564 89 4b 10 mov DWORD PTR [rbx+16], ecx 00567 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3701 : } while (z->num_bits <= 24); 0056b 83 f9 18 cmp ecx, 24 0056e 7f 1a jg SHORT $LN93@stbi__comp 00570 b8 01 00 00 00 mov eax, 1 00575 44 8b c9 mov r9d, ecx 00578 d3 e0 shl eax, cl 0057a 8b d1 mov edx, ecx 0057c 44 3b c0 cmp r8d, eax 0057f 72 bf jb SHORT $LL94@stbi__comp $LN175@stbi__comp: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00581 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 00585 8b ca mov ecx, edx 00587 48 89 03 mov QWORD PTR [rbx], rax $LN93@stbi__comp: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 0058a 8b 7b 14 mov edi, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; 0058d 8b c7 mov eax, edi 0058f c1 e8 07 shr eax, 7 00592 83 e7 7f and edi, 127 ; 0000007fH 00595 89 43 14 mov DWORD PTR [rbx+20], eax ; 3870 : c = stbi__zreceive(a, 7) + 11; 00598 83 c7 0b add edi, 11 ; 3710 : z->num_bits -= n; 0059b 8d 41 f9 lea eax, DWORD PTR [rcx-7] $LN273@stbi__comp: ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); 0059e 89 43 10 mov DWORD PTR [rbx+16], eax $LN18@stbi__comp: 005a1 41 8b c4 mov eax, r12d 005a4 2b c6 sub eax, esi 005a6 3b c7 cmp eax, edi 005a8 7c 66 jl SHORT $LN9@stbi__comp ; 3876 : memset(lencodes + n, fill, c); 005aa 48 63 c6 movsxd rax, esi 005ad 48 8d 8c 24 40 08 00 00 lea rcx, QWORD PTR lencodes$[rsp] 005b5 48 03 c8 add rcx, rax 005b8 44 8b c7 mov r8d, edi 005bb 41 0f b6 d3 movzx edx, r11b 005bf e8 00 00 00 00 call memset $LN11@stbi__comp: ; 3854 : while (n < ntot) { 005c4 03 f7 add esi, edi 005c6 41 3b f4 cmp esi, r12d 005c9 0f 8c 41 fd ff ff jl $LL5@stbi__comp ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); 005cf 75 3f jne SHORT $LN9@stbi__comp ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; 005d1 48 8d 4b 34 lea rcx, QWORD PTR [rbx+52] 005d5 44 8b c5 mov r8d, ebp 005d8 48 8d 94 24 40 08 00 00 lea rdx, QWORD PTR lencodes$[rsp] 005e0 e8 00 00 00 00 call stbi__zbuild_huffman 005e5 85 c0 test eax, eax 005e7 74 4a je SHORT $LN218@stbi__comp ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; 005e9 8b cd mov ecx, ebp 005eb 48 8d 94 24 40 08 00 00 lea rdx, QWORD PTR lencodes$[rsp] 005f3 48 03 d1 add rdx, rcx 005f6 45 8b c7 mov r8d, r15d 005f9 48 8d 8b 18 08 00 00 lea rcx, QWORD PTR [rbx+2072] 00600 e8 00 00 00 00 call stbi__zbuild_huffman 00605 85 c0 test eax, eax 00607 41 0f 95 c5 setne r13b 0060b 41 8b c5 mov eax, r13d 0060e eb 25 jmp SHORT $LN1@stbi__comp $LN9@stbi__comp: ; 3883 : return 1; ; 3884 : } 00610 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00616 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0061f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00624 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00628 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MDNKOBMC@bad?5codelengths@ 0062f 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN218@stbi__comp: 00633 33 c0 xor eax, eax $LN1@stbi__comp: 00635 48 8b bc 24 60 0a 00 00 mov rdi, QWORD PTR [rsp+2656] 0063d 48 8b b4 24 58 0a 00 00 mov rsi, QWORD PTR [rsp+2648] 00645 48 8b 8c 24 10 0a 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0064d 48 33 cc xor rcx, rsp 00650 e8 00 00 00 00 call __security_check_cookie 00655 48 81 c4 20 0a 00 00 add rsp, 2592 ; 00000a20H 0065c 41 5f pop r15 0065e 41 5d pop r13 00660 41 5c pop r12 00662 5d pop rbp 00663 5b pop rbx 00664 c3 ret 0 stbi__compute_huffman_codes ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_uncompressed_block _TEXT SEGMENT header$ = 48 a$ = 48 stbi__parse_uncompressed_block PROC ; COMDAT ; 3887 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) 0000a 8b 51 10 mov edx, DWORD PTR [rcx+16] 0000d 48 8b d9 mov rbx, rcx 00010 8b fa mov edi, edx 00012 83 e7 07 and edi, 7 00015 74 7d je SHORT $LN56@stbi__pars ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00017 3b d7 cmp edx, edi 00019 7d 6a jge SHORT $LN18@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0001b 44 8b 41 14 mov r8d, DWORD PTR [rcx+20] 0001f b8 01 00 00 00 mov eax, 1 00024 8b ca mov ecx, edx ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00026 44 8b d2 mov r10d, edx ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00029 d3 e0 shl eax, cl 0002b 44 8b ca mov r9d, edx 0002e 44 3b c0 cmp r8d, eax 00031 73 48 jae SHORT $LN43@stbi__pars 00033 4c 8b 5b 08 mov r11, QWORD PTR [rbx+8] $LL19@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00037 48 8b 03 mov rax, QWORD PTR [rbx] 0003a 49 3b c3 cmp rax, r11 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0003d 72 04 jb SHORT $LN24@stbi__pars 0003f 32 c9 xor cl, cl 00041 eb 09 jmp SHORT $LN25@stbi__pars $LN24@stbi__pars: 00043 0f b6 08 movzx ecx, BYTE PTR [rax] 00046 48 ff c0 inc rax 00049 48 89 03 mov QWORD PTR [rbx], rax $LN25@stbi__pars: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 0004c 0f b6 c1 movzx eax, cl ; 3700 : z->num_bits += 8; 0004f 41 8d 52 08 lea edx, DWORD PTR [r10+8] 00053 41 8b ca mov ecx, r10d 00056 89 53 10 mov DWORD PTR [rbx+16], edx 00059 d3 e0 shl eax, cl 0005b 44 0b c0 or r8d, eax 0005e 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3701 : } while (z->num_bits <= 24); 00062 83 fa 18 cmp edx, 24 00065 7f 1e jg SHORT $LN18@stbi__pars ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00067 8b ca mov ecx, edx 00069 b8 01 00 00 00 mov eax, 1 0006e d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 00070 44 8b d2 mov r10d, edx 00073 44 8b ca mov r9d, edx 00076 44 3b c0 cmp r8d, eax 00079 72 bc jb SHORT $LL19@stbi__pars $LN43@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 0007b 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 0007f 41 8b d1 mov edx, r9d 00082 48 89 03 mov QWORD PTR [rbx], rax $LN18@stbi__pars: ; 3709 : z->code_buffer >>= n; 00085 8b 43 14 mov eax, DWORD PTR [rbx+20] 00088 8b cf mov ecx, edi 0008a d3 e8 shr eax, cl ; 3710 : z->num_bits -= n; 0008c 2b d7 sub edx, edi 0008e 89 43 14 mov DWORD PTR [rbx+20], eax 00091 89 53 10 mov DWORD PTR [rbx+16], edx $LN56@stbi__pars: ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; 00094 45 33 c0 xor r8d, r8d 00097 8b c2 mov eax, edx ; 3894 : while (a->num_bits > 0) { 00099 85 d2 test edx, edx 0009b 7e 31 jle SHORT $LN3@stbi__pars 0009d 8b 4b 14 mov ecx, DWORD PTR [rbx+20] 000a0 48 8d 54 24 30 lea rdx, QWORD PTR header$[rsp] ; 3710 : z->num_bits -= n; 000a5 44 0f b6 c9 movzx r9d, cl 000a9 0f 1f 80 00 00 00 00 npad 7 $LL2@stbi__pars: ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; 000b0 c1 e9 08 shr ecx, 8 000b3 41 ff c0 inc r8d 000b6 44 88 0a mov BYTE PTR [rdx], r9b 000b9 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] ; 3897 : a->num_bits -= 8; 000bd 83 e8 08 sub eax, 8 000c0 89 4b 14 mov DWORD PTR [rbx+20], ecx 000c3 44 0f b6 c9 movzx r9d, cl 000c7 85 c0 test eax, eax 000c9 7f e5 jg SHORT $LL2@stbi__pars 000cb 89 43 10 mov DWORD PTR [rbx+16], eax $LN3@stbi__pars: ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); 000ce 85 c0 test eax, eax 000d0 79 30 jns SHORT $LN42@stbi__pars $LN72@stbi__pars: ; 3913 : } 000d2 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000d8 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000e1 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000e6 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000ea 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@IECDHMDI@zlib?5corrupt@ 000f1 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN73@stbi__pars: 000f5 33 c0 xor eax, eax 000f7 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 000fc 48 83 c4 20 add rsp, 32 ; 00000020H 00100 5f pop rdi 00101 c3 ret 0 $LN42@stbi__pars: 00102 49 63 c8 movsxd rcx, r8d ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) 00105 48 83 f9 04 cmp rcx, 4 00109 7d 26 jge SHORT $LN50@stbi__pars ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0010b 4c 8b 43 08 mov r8, QWORD PTR [rbx+8] 0010f 48 8b 03 mov rax, QWORD PTR [rbx] $LL4@stbi__pars: 00112 49 3b c0 cmp rax, r8 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00115 72 04 jb SHORT $LN32@stbi__pars 00117 32 d2 xor dl, dl 00119 eb 09 jmp SHORT $LN33@stbi__pars $LN32@stbi__pars: 0011b 0f b6 10 movzx edx, BYTE PTR [rax] 0011e 48 ff c0 inc rax 00121 48 89 03 mov QWORD PTR [rbx], rax $LN33@stbi__pars: ; 3902 : header[k++] = stbi__zget8(a); 00124 88 54 0c 30 mov BYTE PTR header$[rsp+rcx], dl 00128 48 ff c1 inc rcx 0012b 48 83 f9 04 cmp rcx, 4 0012f 7c e1 jl SHORT $LL4@stbi__pars $LN50@stbi__pars: ; 3903 : len = header[1] * 256 + header[0]; 00131 0f b6 44 24 30 movzx eax, BYTE PTR header$[rsp] 00136 44 0f b6 44 24 31 movzx r8d, BYTE PTR header$[rsp+1] ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); 0013c 0f b6 4c 24 33 movzx ecx, BYTE PTR header$[rsp+3] 00141 41 c1 e0 08 shl r8d, 8 00145 44 03 c0 add r8d, eax 00148 c1 e1 08 shl ecx, 8 0014b 0f b6 44 24 32 movzx eax, BYTE PTR header$[rsp+2] 00150 03 c8 add ecx, eax 00152 41 8b c0 mov eax, r8d 00155 35 ff ff 00 00 xor eax, 65535 ; 0000ffffH 0015a 3b c8 cmp ecx, eax 0015c 0f 85 70 ff ff ff jne $LN72@stbi__pars ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); 00162 48 8b 0b mov rcx, QWORD PTR [rbx] 00165 41 8b f8 mov edi, r8d 00168 48 03 cf add rcx, rdi 0016b 48 3b 4b 08 cmp rcx, QWORD PTR [rbx+8] 0016f 76 30 jbe SHORT $LN9@stbi__pars ; 431 : stbi__g_failure_reason = str; 00171 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00177 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00180 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00185 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00189 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@PIPBCKIA@read?5past?5buffer@ 00190 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); 00194 33 c0 xor eax, eax ; 3913 : } 00196 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 0019b 48 83 c4 20 add rsp, 32 ; 00000020H 0019f 5f pop rdi 001a0 c3 ret 0 $LN9@stbi__pars: ; 3907 : if (a->zout + len > a->zout_end) 001a1 48 8b 53 18 mov rdx, QWORD PTR [rbx+24] 001a5 49 8d 04 10 lea rax, QWORD PTR [r8+rdx] 001a9 48 3b 43 28 cmp rax, QWORD PTR [rbx+40] 001ad 76 10 jbe SHORT $LN57@stbi__pars ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; 001af 48 8b cb mov rcx, rbx 001b2 e8 00 00 00 00 call stbi__zexpand 001b7 85 c0 test eax, eax 001b9 0f 84 36 ff ff ff je $LN73@stbi__pars $LN57@stbi__pars: ; 3909 : memcpy(a->zout, a->zbuffer, len); 001bf 48 8b 13 mov rdx, QWORD PTR [rbx] 001c2 4c 8b c7 mov r8, rdi 001c5 48 8b 4b 18 mov rcx, QWORD PTR [rbx+24] 001c9 e8 00 00 00 00 call memcpy ; 3910 : a->zbuffer += len; 001ce 48 01 3b add QWORD PTR [rbx], rdi ; 3911 : a->zout += len; ; 3912 : return 1; 001d1 b8 01 00 00 00 mov eax, 1 001d6 48 01 7b 18 add QWORD PTR [rbx+24], rdi ; 3913 : } 001da 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 001df 48 83 c4 20 add rsp, 32 ; 00000020H 001e3 5f pop rdi 001e4 c3 ret 0 stbi__parse_uncompressed_block ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_zlib_header _TEXT SEGMENT a$ = 8 stbi__parse_zlib_header PROC ; COMDAT ; 3916 : { 00000 48 8b d1 mov rdx, rcx ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00003 48 8b 09 mov rcx, QWORD PTR [rcx] 00006 4c 8b 4a 08 mov r9, QWORD PTR [rdx+8] 0000a 49 3b c9 cmp rcx, r9 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0000d 0f 83 b1 00 00 00 jae $LN29@stbi__pars 00013 0f b6 01 movzx eax, BYTE PTR [rcx] 00016 4c 8d 51 01 lea r10, QWORD PTR [rcx+1] ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; 0001a 44 8b d8 mov r11d, eax ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0001d 4c 89 12 mov QWORD PTR [rdx], r10 ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; 00020 41 83 e3 0f and r11d, 15 00024 44 8b c0 mov r8d, eax ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00027 4d 3b d1 cmp r10, r9 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0002a 0f 83 94 00 00 00 jae $LN29@stbi__pars 00030 41 0f b6 0a movzx ecx, BYTE PTR [r10] 00034 49 8d 42 01 lea rax, QWORD PTR [r10+1] 00038 48 89 02 mov QWORD PTR [rdx], rax ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0003b 49 3b c1 cmp rax, r9 ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec 0003e 0f 83 80 00 00 00 jae $LN29@stbi__pars ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec 00044 41 c1 e0 08 shl r8d, 8 00048 b8 85 10 42 08 mov eax, 138547333 ; 08421085H 0004d 44 03 c1 add r8d, ecx 00050 41 f7 e0 mul r8d 00053 41 8b c0 mov eax, r8d 00056 2b c2 sub eax, edx 00058 d1 e8 shr eax, 1 0005a 03 c2 add eax, edx 0005c c1 e8 04 shr eax, 4 0005f 6b c0 1f imul eax, eax, 31 00062 44 3b c0 cmp r8d, eax 00065 75 5d jne SHORT $LN29@stbi__pars ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png 00067 f6 c1 20 test cl, 32 ; 00000020H 0006a 74 26 je SHORT $LN4@stbi__pars ; 431 : stbi__g_failure_reason = str; 0006c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00072 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 ; 3927 : } 0007b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason ; 431 : stbi__g_failure_reason = str; 00080 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00084 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@DOGMHEBI@no?5preset?5dict@ ; 3927 : } 0008b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 0008f 33 c0 xor eax, eax 00091 c3 ret 0 $LN4@stbi__pars: ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png 00092 41 83 fb 08 cmp r11d, 8 00096 74 26 je SHORT $LN5@stbi__pars ; 431 : stbi__g_failure_reason = str; 00098 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0009e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 ; 3927 : } 000a7 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason ; 431 : stbi__g_failure_reason = str; 000ac 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000b0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MCNBDLPD@bad?5compression@ ; 3927 : } 000b7 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 000bb 33 c0 xor eax, eax 000bd c3 ret 0 $LN5@stbi__pars: ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; 000be b8 01 00 00 00 mov eax, 1 ; 3927 : } 000c3 c3 ret 0 $LN29@stbi__pars: 000c4 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000ca 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000d3 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000d8 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000dc 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@OBKOPAFL@bad?5zlib?5header@ 000e3 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 000e7 33 c0 xor eax, eax 000e9 c3 ret 0 stbi__parse_zlib_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_zlib _TEXT SEGMENT a$ = 48 parse_header$ = 56 stbi__parse_zlib PROC ; COMDAT ; 3959 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 48 89 7c 24 18 mov QWORD PTR [rsp+24], rdi 0000f 41 56 push r14 00011 48 83 ec 20 sub rsp, 32 ; 00000020H 00015 48 8b d9 mov rbx, rcx ; 3960 : int final, type; ; 3961 : if (parse_header) 00018 85 d2 test edx, edx 0001a 0f 84 de 00 00 00 je $LN98@stbi__pars ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00020 48 8b 11 mov rdx, QWORD PTR [rcx] 00023 4c 8b 49 08 mov r9, QWORD PTR [rcx+8] 00027 49 3b d1 cmp rdx, r9 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0002a 73 4a jae SHORT $LN100@stbi__pars 0002c 0f b6 02 movzx eax, BYTE PTR [rdx] 0002f 48 ff c2 inc rdx ; 3918 : int cm = cmf & 15; 00032 44 8b d0 mov r10d, eax ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00035 48 89 11 mov QWORD PTR [rcx], rdx ; 3918 : int cm = cmf & 15; 00038 41 83 e2 0f and r10d, 15 0003c 44 8b c0 mov r8d, eax ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0003f 49 3b d1 cmp rdx, r9 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 00042 73 32 jae SHORT $LN100@stbi__pars 00044 0f b6 0a movzx ecx, BYTE PTR [rdx] 00047 48 8d 42 01 lea rax, QWORD PTR [rdx+1] 0004b 48 89 03 mov QWORD PTR [rbx], rax ; 3684 : return (z->zbuffer >= z->zbuffer_end); 0004e 49 3b c1 cmp rax, r9 ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec 00051 73 23 jae SHORT $LN100@stbi__pars ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec 00053 41 c1 e0 08 shl r8d, 8 00057 b8 85 10 42 08 mov eax, 138547333 ; 08421085H 0005c 44 03 c1 add r8d, ecx 0005f 41 f7 e0 mul r8d 00062 41 8b c0 mov eax, r8d 00065 2b c2 sub eax, edx 00067 d1 e8 shr eax, 1 00069 03 c2 add eax, edx 0006b c1 e8 04 shr eax, 4 0006e 6b c0 1f imul eax, eax, 31 00071 44 3b c0 cmp r8d, eax 00074 74 3b je SHORT $LN21@stbi__pars $LN100@stbi__pars: ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; 00076 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0007c 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00085 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0008a 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0008e 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@OBKOPAFL@bad?5zlib?5header@ $LN126@stbi__pars: 00095 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN88@stbi__pars: 00099 33 c0 xor eax, eax $LN1@stbi__pars: ; 3987 : } 0009b 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000a0 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 000a5 48 8b 7c 24 40 mov rdi, QWORD PTR [rsp+64] 000aa 48 83 c4 20 add rsp, 32 ; 00000020H 000ae 41 5e pop r14 000b0 c3 ret 0 $LN21@stbi__pars: ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png 000b1 f6 c1 20 test cl, 32 ; 00000020H 000b4 74 21 je SHORT $LN22@stbi__pars ; 431 : stbi__g_failure_reason = str; 000b6 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000bc 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000c5 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000ca 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000ce 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@DOGMHEBI@no?5preset?5dict@ ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png 000d5 eb be jmp SHORT $LN126@stbi__pars $LN22@stbi__pars: ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png 000d7 41 83 fa 08 cmp r10d, 8 000db 74 21 je SHORT $LN98@stbi__pars ; 431 : stbi__g_failure_reason = str; 000dd 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000e3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000ec b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000f1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000f5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MCNBDLPD@bad?5compression@ ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png 000fc eb 97 jmp SHORT $LN126@stbi__pars $LN98@stbi__pars: ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; 000fe 33 c0 xor eax, eax 00100 48 89 43 10 mov QWORD PTR [rbx+16], rax $LL4@stbi__pars: ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00104 8b 4b 10 mov ecx, DWORD PTR [rbx+16] 00107 83 f9 01 cmp ecx, 1 0010a 7d 61 jge SHORT $LN52@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 0010c 8b 53 14 mov edx, DWORD PTR [rbx+20] 0010f b8 01 00 00 00 mov eax, 1 00114 d3 e0 shl eax, cl 00116 44 8b c1 mov r8d, ecx 00119 44 8b c9 mov r9d, ecx 0011c 3b d0 cmp edx, eax 0011e 73 43 jae SHORT $LN80@stbi__pars 00120 4c 8b 53 08 mov r10, QWORD PTR [rbx+8] $LL53@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 00124 48 8b 03 mov rax, QWORD PTR [rbx] 00127 49 3b c2 cmp rax, r10 ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 0012a 72 04 jb SHORT $LN58@stbi__pars 0012c 32 c9 xor cl, cl 0012e eb 09 jmp SHORT $LN59@stbi__pars $LN58@stbi__pars: 00130 0f b6 08 movzx ecx, BYTE PTR [rax] 00133 48 ff c0 inc rax 00136 48 89 03 mov QWORD PTR [rbx], rax $LN59@stbi__pars: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 00139 0f b6 c1 movzx eax, cl 0013c 41 8b c8 mov ecx, r8d 0013f d3 e0 shl eax, cl ; 3700 : z->num_bits += 8; 00141 41 8d 48 08 lea ecx, DWORD PTR [r8+8] 00145 0b d0 or edx, eax 00147 89 4b 10 mov DWORD PTR [rbx+16], ecx 0014a 89 53 14 mov DWORD PTR [rbx+20], edx ; 3701 : } while (z->num_bits <= 24); 0014d 83 f9 18 cmp ecx, 24 00150 7f 1b jg SHORT $LN52@stbi__pars 00152 b8 01 00 00 00 mov eax, 1 00157 44 8b c1 mov r8d, ecx 0015a d3 e0 shl eax, cl 0015c 44 8b c9 mov r9d, ecx 0015f 3b d0 cmp edx, eax 00161 72 c1 jb SHORT $LL53@stbi__pars $LN80@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 00163 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 00167 41 8b c9 mov ecx, r9d 0016a 48 89 03 mov QWORD PTR [rbx], rax $LN52@stbi__pars: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 0016d 44 8b 43 14 mov r8d, DWORD PTR [rbx+20] ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; 00171 8d 51 ff lea edx, DWORD PTR [rcx-1] 00174 41 8b f0 mov esi, r8d 00177 89 53 10 mov DWORD PTR [rbx+16], edx 0017a 41 d1 e8 shr r8d, 1 0017d 83 e6 01 and esi, 1 00180 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); 00184 83 fa 02 cmp edx, 2 00187 7d 6e jge SHORT $LN67@stbi__pars ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 00189 8b ca mov ecx, edx 0018b b8 01 00 00 00 mov eax, 1 00190 d3 e0 shl eax, cl 00192 45 8b c8 mov r9d, r8d 00195 44 8b d2 mov r10d, edx 00198 44 8b da mov r11d, edx 0019b 44 3b c0 cmp r8d, eax 0019e 73 4d jae SHORT $LN81@stbi__pars 001a0 48 8b 7b 08 mov rdi, QWORD PTR [rbx+8] $LL68@stbi__pars: ; 3684 : return (z->zbuffer >= z->zbuffer_end); 001a4 48 8b 03 mov rax, QWORD PTR [rbx] 001a7 48 3b c7 cmp rax, rdi ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; 001aa 72 04 jb SHORT $LN73@stbi__pars 001ac 32 c9 xor cl, cl 001ae eb 09 jmp SHORT $LN74@stbi__pars $LN73@stbi__pars: 001b0 0f b6 08 movzx ecx, BYTE PTR [rax] 001b3 48 ff c0 inc rax 001b6 48 89 03 mov QWORD PTR [rbx], rax $LN74@stbi__pars: ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; 001b9 44 0f b6 c1 movzx r8d, cl ; 3700 : z->num_bits += 8; 001bd 41 8d 53 08 lea edx, DWORD PTR [r11+8] 001c1 41 8b ca mov ecx, r10d 001c4 89 53 10 mov DWORD PTR [rbx+16], edx 001c7 41 d3 e0 shl r8d, cl 001ca 45 0b c1 or r8d, r9d 001cd 44 89 43 14 mov DWORD PTR [rbx+20], r8d ; 3701 : } while (z->num_bits <= 24); 001d1 83 fa 18 cmp edx, 24 001d4 7f 21 jg SHORT $LN67@stbi__pars ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { 001d6 8b ca mov ecx, edx 001d8 b8 01 00 00 00 mov eax, 1 001dd d3 e0 shl eax, cl ; 3701 : } while (z->num_bits <= 24); 001df 45 8b c8 mov r9d, r8d 001e2 44 8b d2 mov r10d, edx 001e5 44 8b da mov r11d, edx 001e8 44 3b c0 cmp r8d, eax 001eb 72 b7 jb SHORT $LL68@stbi__pars $LN81@stbi__pars: ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ 001ed 48 8b 43 08 mov rax, QWORD PTR [rbx+8] 001f1 45 8b c1 mov r8d, r9d 001f4 48 89 03 mov QWORD PTR [rbx], rax $LN67@stbi__pars: ; 3708 : k = z->code_buffer & ((1 << n) - 1); 001f7 41 8b c8 mov ecx, r8d ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; 001fa 8d 42 fe lea eax, DWORD PTR [rdx-2] 001fd 41 c1 e8 02 shr r8d, 2 00201 44 89 43 14 mov DWORD PTR [rbx+20], r8d 00205 89 43 10 mov DWORD PTR [rbx+16], eax 00208 83 e1 03 and ecx, 3 ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { 0020b 75 0a jne SHORT $LN7@stbi__pars ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; 0020d 48 8b cb mov rcx, rbx 00210 e8 00 00 00 00 call stbi__parse_uncompressed_block ; 3970 : } 00215 eb 5f jmp SHORT $LN123@stbi__pars $LN7@stbi__pars: ; 3971 : else if (type == 3) { 00217 83 f9 03 cmp ecx, 3 0021a 0f 84 79 fe ff ff je $LN88@stbi__pars ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { 00220 83 f9 01 cmp ecx, 1 00223 75 39 jne SHORT $LN12@stbi__pars ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; 00225 48 8d 4b 34 lea rcx, QWORD PTR [rbx+52] 00229 41 b8 20 01 00 00 mov r8d, 288 ; 00000120H 0022f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:stbi__zdefault_length 00236 e8 00 00 00 00 call stbi__zbuild_huffman 0023b 85 c0 test eax, eax 0023d 0f 84 56 fe ff ff je $LN88@stbi__pars ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; 00243 48 8d 8b 18 08 00 00 lea rcx, QWORD PTR [rbx+2072] 0024a 41 b8 20 00 00 00 mov r8d, 32 ; 00000020H 00250 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:stbi__zdefault_distance 00257 e8 00 00 00 00 call stbi__zbuild_huffman ; 3979 : } 0025c eb 08 jmp SHORT $LN125@stbi__pars $LN12@stbi__pars: ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; 0025e 48 8b cb mov rcx, rbx 00261 e8 00 00 00 00 call stbi__compute_huffman_codes $LN125@stbi__pars: ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; 00266 85 c0 test eax, eax 00268 0f 84 2b fe ff ff je $LN88@stbi__pars 0026e 48 8b cb mov rcx, rbx 00271 e8 00 00 00 00 call stbi__parse_huffman_block $LN123@stbi__pars: ; 3984 : } ; 3985 : } while (!final); 00276 85 c0 test eax, eax 00278 0f 84 1b fe ff ff je $LN88@stbi__pars 0027e 85 f6 test esi, esi 00280 0f 84 7e fe ff ff je $LL4@stbi__pars ; 3986 : return 1; 00286 b8 01 00 00 00 mov eax, 1 0028b e9 0b fe ff ff jmp $LN1@stbi__pars stbi__parse_zlib ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__do_zlib _TEXT SEGMENT a$ = 8 obuf$ = 16 olen$ = 24 exp$dead$ = 32 parse_header$ = 40 stbi__do_zlib PROC ; COMDAT ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; 00000 49 63 c0 movsxd rax, r8d 00003 48 03 c2 add rax, rdx 00006 48 89 51 20 mov QWORD PTR [rcx+32], rdx 0000a 48 89 51 18 mov QWORD PTR [rcx+24], rdx ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); 0000e 8b 54 24 28 mov edx, DWORD PTR parse_header$[rsp] 00012 48 89 41 28 mov QWORD PTR [rcx+40], rax 00016 c7 41 30 01 00 00 00 mov DWORD PTR [rcx+48], 1 0001d e9 00 00 00 00 jmp stbi__parse_zlib stbi__do_zlib ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi_zlib_decode_malloc_guesssize_headerflag _TEXT SEGMENT a$ = 32 __$ArrayPad$ = 4128 buffer$ = 4192 len$ = 4200 initial_size$ = 4208 outlen$ = 4216 parse_header$ = 4224 stbi_zlib_decode_malloc_guesssize_headerflag PROC ; COMDAT ; 4022 : { $LN16: 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 b8 38 10 00 00 mov eax, 4152 ; 00001038H 0000a e8 00 00 00 00 call __chkstk 0000f 48 2b e0 sub rsp, rax 00012 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00019 48 33 c4 xor rax, rsp 0001c 48 89 84 24 20 10 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); 00024 49 63 f0 movsxd rsi, r8d 00027 48 8b f9 mov rdi, rcx ; 438 : return STBI_MALLOC(size); 0002a 48 8b ce mov rcx, rsi ; 4022 : { 0002d 48 63 ea movsxd rbp, edx 00030 49 8b d9 mov rbx, r9 ; 438 : return STBI_MALLOC(size); 00033 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 4025 : if (p == NULL) return NULL; 00039 48 85 c0 test rax, rax 0003c 74 5d je SHORT $LN14@stbi_zlib_ ; 3996 : return stbi__parse_zlib(a, parse_header); 0003e 8b 94 24 80 10 00 00 mov edx, DWORD PTR parse_header$[rsp] 00045 48 8d 4c 24 20 lea rcx, QWORD PTR a$[rsp] 0004a 48 89 44 24 40 mov QWORD PTR a$[rsp+32], rax ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; 0004f 48 03 ef add rbp, rdi ; 3992 : a->zout = obuf; 00052 48 89 44 24 38 mov QWORD PTR a$[rsp+24], rax ; 3993 : a->zout_end = obuf + olen; 00057 48 03 c6 add rax, rsi 0005a 48 89 44 24 48 mov QWORD PTR a$[rsp+40], rax ; 4026 : a.zbuffer = (stbi_uc*)buffer; 0005f 48 89 7c 24 20 mov QWORD PTR a$[rsp], rdi ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; 00064 48 89 6c 24 28 mov QWORD PTR a$[rsp+8], rbp ; 3994 : a->z_expandable = exp; 00069 c7 44 24 50 01 00 00 00 mov DWORD PTR a$[rsp+48], 1 ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); 00071 e8 00 00 00 00 call stbi__parse_zlib ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { 00076 85 c0 test eax, eax 00078 74 16 je SHORT $LN3@stbi_zlib_ ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); 0007a 48 85 db test rbx, rbx 0007d 74 0a je SHORT $LN5@stbi_zlib_ 0007f 8b 44 24 38 mov eax, DWORD PTR a$[rsp+24] 00083 2b 44 24 40 sub eax, DWORD PTR a$[rsp+32] 00087 89 03 mov DWORD PTR [rbx], eax $LN5@stbi_zlib_: ; 4030 : return a.zout_start; 00089 48 8b 44 24 40 mov rax, QWORD PTR a$[rsp+32] 0008e eb 0d jmp SHORT $LN4@stbi_zlib_ $LN3@stbi_zlib_: ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); 00090 48 8b 4c 24 40 mov rcx, QWORD PTR a$[rsp+32] 00095 ff 15 00 00 00 00 call QWORD PTR __imp_free $LN14@stbi_zlib_: ; 4034 : return NULL; ; 4035 : } ; 4036 : } 0009b 33 c0 xor eax, eax $LN4@stbi_zlib_: 0009d 48 8b 8c 24 20 10 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 000a5 48 33 cc xor rcx, rsp 000a8 e8 00 00 00 00 call __security_check_cookie 000ad 48 81 c4 38 10 00 00 add rsp, 4152 ; 00001038H 000b4 5f pop rdi 000b5 5e pop rsi 000b6 5d pop rbp 000b7 5b pop rbx 000b8 c3 ret 0 stbi_zlib_decode_malloc_guesssize_headerflag ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__get_chunk_header _TEXT SEGMENT s$ = 48 stbi__get_chunk_header PROC ; COMDAT ; 4096 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H 0000f 48 8b f1 mov rsi, rcx ; 1168 : stbi__uint32 z = stbi__get16be(s); 00012 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00017 48 8b ce mov rcx, rsi 0001a 8b f8 mov edi, eax 0001c e8 00 00 00 00 call stbi__get16be 00021 c1 e7 10 shl edi, 16 ; 1168 : stbi__uint32 z = stbi__get16be(s); 00024 48 8b ce mov rcx, rsi ; 1169 : return (z << 16) + stbi__get16be(s); 00027 03 f8 add edi, eax ; 1168 : stbi__uint32 z = stbi__get16be(s); 00029 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 0002e 48 8b ce mov rcx, rsi 00031 8b d8 mov ebx, eax 00033 e8 00 00 00 00 call stbi__get16be ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } 00038 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] ; 1169 : return (z << 16) + stbi__get16be(s); 0003d c1 e3 10 shl ebx, 16 00040 03 c3 add eax, ebx ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } 00042 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00047 48 c1 e0 20 shl rax, 32 ; 00000020H 0004b 48 0b c7 or rax, rdi 0004e 48 83 c4 20 add rsp, 32 ; 00000020H 00052 5f pop rdi 00053 c3 ret 0 stbi__get_chunk_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__check_png_header _TEXT SEGMENT s$ = 48 stbi__check_png_header PROC ; COMDAT ; 4104 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H 0000f 48 8b d9 mov rbx, rcx 00012 48 8d 35 00 00 00 00 lea rsi, OFFSET FLAT:?png_sig@?1??stbi__check_png_header@@9@9 00019 33 ff xor edi, edi 0001b 0f 1f 44 00 00 npad 5 $LL4@stbi__chec: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00020 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00027 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0002e 73 0f jae SHORT $LN8@stbi__chec ; 1078 : return *s->img_buffer++; 00030 0f b6 08 movzx ecx, BYTE PTR [rax] 00033 48 ff c0 inc rax 00036 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0003d eb 26 jmp SHORT $LN7@stbi__chec $LN8@stbi__chec: ; 1079 : if (s->read_from_callbacks) { 0003f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00043 74 1e je SHORT $LN9@stbi__chec ; 1080 : stbi__refill_buffer(s); 00045 48 8b cb mov rcx, rbx 00048 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0004d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00054 0f b6 08 movzx ecx, BYTE PTR [rax] 00057 48 ff c0 inc rax 0005a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00061 eb 02 jmp SHORT $LN7@stbi__chec $LN9@stbi__chec: ; 1082 : } ; 1083 : return 0; 00063 32 c9 xor cl, cl $LN7@stbi__chec: ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); 00065 3a 0c 37 cmp cl, BYTE PTR [rdi+rsi] 00068 75 1e jne SHORT $LN14@stbi__chec ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) 0006a 48 ff c7 inc rdi 0006d 48 83 ff 08 cmp rdi, 8 00071 7c ad jl SHORT $LL4@stbi__chec ; 4109 : return 1; 00073 b8 01 00 00 00 mov eax, 1 ; 4110 : } 00078 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0007d 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 00082 48 83 c4 20 add rsp, 32 ; 00000020H 00086 5f pop rdi 00087 c3 ret 0 $LN14@stbi__chec: ; 431 : stbi__g_failure_reason = str; 00088 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00091 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index ; 4110 : } 00097 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0009c 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] ; 431 : stbi__g_failure_reason = str; 000a1 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 000a6 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 000aa 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0M@DMDNBACF@bad?5png?5sig@ 000b1 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); 000b5 33 c0 xor eax, eax ; 4110 : } 000b7 48 83 c4 20 add rsp, 32 ; 00000020H 000bb 5f pop rdi 000bc c3 ret 0 stbi__check_png_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__paeth _TEXT SEGMENT a$ = 8 b$ = 16 c$ = 24 stbi__paeth PROC ; COMDAT ; 4140 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 8b da mov ebx, edx ; 4141 : int p = a + b - c; 00007 44 8b c9 mov r9d, ecx 0000a 45 2b c8 sub r9d, r8d 0000d 45 8d 14 11 lea r10d, DWORD PTR [r9+rdx] ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); 00011 41 8b d1 mov edx, r9d 00014 41 8b c2 mov eax, r10d 00017 2b c1 sub eax, ecx 00019 44 8b d8 mov r11d, eax 0001c 41 f7 db neg r11d 0001f 44 0f 48 d8 cmovs r11d, eax 00023 f7 da neg edx 00025 41 0f 48 d1 cmovs edx, r9d ; 4144 : int pc = abs(p - c); 00029 45 2b d0 sub r10d, r8d 0002c 41 8b c2 mov eax, r10d 0002f f7 d8 neg eax 00031 41 0f 48 c2 cmovs eax, r10d ; 4145 : if (pa <= pb && pa <= pc) return a; 00035 44 3b da cmp r11d, edx 00038 7f 0d jg SHORT $LN2@stbi__paet 0003a 44 3b d8 cmp r11d, eax 0003d 7f 08 jg SHORT $LN2@stbi__paet 0003f 8b c1 mov eax, ecx ; 4147 : return c; ; 4148 : } 00041 48 8b 5c 24 08 mov rbx, QWORD PTR [rsp+8] 00046 c3 ret 0 $LN2@stbi__paet: ; 4146 : if (pb <= pc) return b; 00047 3b d0 cmp edx, eax 00049 44 0f 4e c3 cmovle r8d, ebx ; 4147 : return c; ; 4148 : } 0004d 48 8b 5c 24 08 mov rbx, QWORD PTR [rsp+8] 00052 41 8b c0 mov eax, r8d 00055 c3 ret 0 stbi__paeth ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__create_png_image_raw _TEXT SEGMENT a$1$ = 32 $T13 = 40 $T14 = 48 stride$1$ = 56 nk$1$ = 64 cur$8$ = 64 width$1$ = 72 j$1$ = 76 filter_bytes$1$ = 80 img_width_bytes$1$ = 84 prior$4$ = 88 cur$9$ = 96 $T15 = 104 tv5788 = 112 tv5875 = 120 tv5731 = 128 tv5728 = 136 tv5835 = 144 $T16 = 152 cur$1$ = 160 img_n$1$ = 240 a$ = 240 raw$ = 248 raw_len$ = 256 out_n$ = 264 x$ = 272 y$ = 280 depth$ = 288 color$ = 296 stbi__create_png_image_raw PROC ; COMDAT ; 4154 : { 00000 44 89 4c 24 20 mov DWORD PTR [rsp+32], r9d 00005 53 push rbx 00006 55 push rbp 00007 56 push rsi 00008 57 push rdi 00009 41 54 push r12 0000b 41 56 push r14 0000d 41 57 push r15 0000f 48 81 ec b0 00 00 00 sub rsp, 176 ; 000000b0H ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; 00016 44 8b bc 24 10 01 00 00 mov r15d, DWORD PTR x$[rsp] 0001e 41 8b c1 mov eax, r9d 00021 44 8b b4 24 20 01 00 00 mov r14d, DWORD PTR depth$[rsp] 00029 41 8b e8 mov ebp, r8d 0002c 44 8b 8c 24 18 01 00 00 mov r9d, DWORD PTR y$[rsp] 00034 45 33 c0 xor r8d, r8d 00037 41 83 fe 10 cmp r14d, 16 0003b 4c 89 44 24 78 mov QWORD PTR tv5875[rsp], r8 00040 45 8b d0 mov r10d, r8d ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; 00043 44 89 7c 24 48 mov DWORD PTR width$1$[rsp], r15d 00048 41 0f 94 c2 sete r10b 0004c 48 8b f1 mov rsi, rcx 0004f 41 ff c2 inc r10d 00052 48 8b da mov rbx, rdx 00055 41 8b fa mov edi, r10d 00058 0f af f8 imul edi, eax 0005b 48 8b 01 mov rax, QWORD PTR [rcx] 0005e 8b 48 08 mov ecx, DWORD PTR [rax+8] 00061 44 8b df mov r11d, edi 00064 45 0f af df imul r11d, r15d 00068 44 8b e1 mov r12d, ecx 0006b 45 0f af e2 imul r12d, r10d 0006f 89 8c 24 f0 00 00 00 mov DWORD PTR img_n$1$[rsp], ecx 00076 44 89 5c 24 38 mov DWORD PTR stride$1$[rsp], r11d 0007b 44 89 64 24 50 mov DWORD PTR filter_bytes$1$[rsp], r12d ; 467 : if (a < 0 || b < 0) return 0; 00080 45 85 ff test r15d, r15d 00083 0f 88 ba 11 00 00 js $LN388@stbi__crea 00089 45 85 c9 test r9d, r9d 0008c 0f 88 b1 11 00 00 js $LN388@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00092 74 13 je SHORT $LN390@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00094 33 d2 xor edx, edx 00096 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0009b 41 f7 f1 div r9d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0009e 44 3b f8 cmp r15d, eax 000a1 0f 8f 9c 11 00 00 jg $LN388@stbi__crea $LN390@stbi__crea: 000a7 41 8b cf mov ecx, r15d 000aa 41 0f af c9 imul ecx, r9d ; 467 : if (a < 0 || b < 0) return 0; 000ae 85 c9 test ecx, ecx 000b0 0f 88 8d 11 00 00 js $LN388@stbi__crea 000b6 85 ff test edi, edi 000b8 0f 88 85 11 00 00 js $LN388@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000be 74 10 je SHORT $LN389@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000c0 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 000c5 99 cdq 000c6 f7 ff idiv edi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 000c8 3b c8 cmp ecx, eax 000ca 0f 8f 73 11 00 00 jg $LN388@stbi__crea $LN389@stbi__crea: 000d0 41 8b c1 mov eax, r9d 000d3 41 0f af c3 imul eax, r11d ; 509 : return stbi__malloc(a * b * c + add); 000d7 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 000da ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into 000e0 48 89 46 18 mov QWORD PTR [rsi+24], rax ; 438 : return STBI_MALLOC(size); 000e4 4c 8b d0 mov r10, rax ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); 000e7 48 85 c0 test rax, rax 000ea 0f 84 57 11 00 00 je $LN387@stbi__crea ; 467 : if (a < 0 || b < 0) return 0; 000f0 4c 63 9c 24 f0 00 00 00 movsxd r11, DWORD PTR img_n$1$[rsp] 000f8 4c 89 ac 24 f8 00 00 00 mov QWORD PTR [rsp+248], r13 00100 45 85 db test r11d, r11d 00103 0f 88 16 11 00 00 js $LN384@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00109 45 85 ff test r15d, r15d 0010c 74 13 je SHORT $LN386@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0010e 33 d2 xor edx, edx 00110 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00115 41 f7 f7 div r15d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00118 44 3b d8 cmp r11d, eax 0011b 0f 8f fe 10 00 00 jg $LN384@stbi__crea $LN386@stbi__crea: 00121 45 8b eb mov r13d, r11d 00124 45 0f af ef imul r13d, r15d 00128 44 89 6c 24 20 mov DWORD PTR a$1$[rsp], r13d ; 467 : if (a < 0 || b < 0) return 0; 0012d 45 85 ed test r13d, r13d 00130 0f 88 e9 10 00 00 js $LN384@stbi__crea 00136 45 85 f6 test r14d, r14d 00139 0f 88 e0 10 00 00 js $LN384@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0013f 74 13 je SHORT $LN385@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00141 33 d2 xor edx, edx 00143 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00148 41 f7 f6 div r14d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0014b 44 3b e8 cmp r13d, eax 0014e 0f 8f cb 10 00 00 jg $LN384@stbi__crea $LN385@stbi__crea: 00154 41 8b c5 mov eax, r13d 00157 41 0f af c6 imul eax, r14d ; 460 : return a <= INT_MAX - b; 0015b 3d f8 ff ff 7f cmp eax, 2147483640 ; 7ffffff8H ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00160 0f 8f b9 10 00 00 jg $LN384@stbi__crea ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); 00166 8b b4 24 18 01 00 00 mov esi, DWORD PTR y$[rsp] 0016d 41 8b cd mov ecx, r13d 00170 41 0f af ce imul ecx, r14d 00174 83 c1 07 add ecx, 7 00177 c1 e9 03 shr ecx, 3 0017a 89 4c 24 54 mov DWORD PTR img_width_bytes$1$[rsp], ecx ; 4172 : img_len = (img_width_bytes + 1) * y; 0017e 8d 41 01 lea eax, DWORD PTR [rcx+1] 00181 0f af c6 imul eax, esi ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); 00184 3b e8 cmp ebp, eax 00186 73 3f jae SHORT $LN100@stbi__crea ; 431 : stbi__g_failure_reason = str; 00188 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0018e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00197 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0019c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001a0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BC@BHMPBBMG@not?5enough?5pixels@ $LN651@stbi__crea: 001a7 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); 001ab 33 c0 xor eax, eax $LN649@stbi__crea: 001ad 4c 8b ac 24 f8 00 00 00 mov r13, QWORD PTR [rsp+248] $LN1@stbi__crea: ; 4370 : } 001b5 48 81 c4 b0 00 00 00 add rsp, 176 ; 000000b0H 001bc 41 5f pop r15 001be 41 5e pop r14 001c0 41 5c pop r12 001c2 5f pop rdi 001c3 5e pop rsi 001c4 5d pop rbp 001c5 5b pop rbx 001c6 c3 ret 0 $LN100@stbi__crea: ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { 001c7 45 33 c9 xor r9d, r9d 001ca 4c 89 54 24 30 mov QWORD PTR $T14[rsp], r10 001cf 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 001d6 41 8b d1 mov edx, r9d 001d9 89 54 24 4c mov DWORD PTR j$1$[rsp], edx 001dd 85 f6 test esi, esi 001df 0f 84 71 0b 00 00 je $LN3@stbi__crea ; 4180 : stbi_uc* cur = a->out + stride * j; 001e5 8b 44 24 20 mov eax, DWORD PTR a$1$[rsp] 001e9 4d 8b c3 mov r8, r11 001ec 4c 63 ef movsxd r13, edi 001ef 49 8b fa mov rdi, r10 001f2 4d 63 f4 movsxd r14, r12d 001f5 4c 89 74 24 68 mov QWORD PTR $T15[rsp], r14 001fa 4c 89 ac 24 98 00 00 00 mov QWORD PTR $T16[rsp], r13 00202 4c 89 5c 24 28 mov QWORD PTR $T13[rsp], r11 00207 89 44 24 20 mov DWORD PTR a$1$[rsp], eax 0020b 4c 89 54 24 30 mov QWORD PTR $T14[rsp], r10 00210 4c 89 94 24 a0 00 00 00 mov QWORD PTR cur$1$[rsp], r10 00218 0f 1f 84 00 00 00 00 00 npad 8 $LL4@stbi__crea: ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; 00220 44 0f b6 13 movzx r10d, BYTE PTR [rbx] 00224 8b ea mov ebp, edx 00226 0f af 6c 24 38 imul ebp, DWORD PTR stride$1$[rsp] 0022b 48 ff c3 inc rbx 0022e 48 03 ef add rbp, rdi 00231 48 89 6c 24 60 mov QWORD PTR cur$9$[rsp], rbp 00236 48 8b f5 mov rsi, rbp ; 4183 : ; 4184 : if (filter > 4) 00239 41 83 fa 04 cmp r10d, 4 0023d 0f 87 db 0a 00 00 ja $LN260@stbi__crea ; 4186 : ; 4187 : if (depth < 8) { 00243 83 bc 24 20 01 00 00 08 cmp DWORD PTR depth$[rsp], 8 0024b 7d 30 jge SHORT $LN102@stbi__crea ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); 0024d 41 3b cf cmp ecx, r15d 00250 0f 87 a4 0a 00 00 ja $LN261@stbi__crea ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place 00256 8b 84 24 08 01 00 00 mov eax, DWORD PTR out_n$[rsp] ; 4190 : filter_bytes = 1; 0025d 41 bc 01 00 00 00 mov r12d, 1 00263 41 0f af c7 imul eax, r15d 00267 45 8b f4 mov r14d, r12d 0026a 44 89 64 24 50 mov DWORD PTR filter_bytes$1$[rsp], r12d 0026f 4c 89 64 24 68 mov QWORD PTR $T15[rsp], r12 ; 4191 : width = img_width_bytes; 00274 89 4c 24 48 mov DWORD PTR width$1$[rsp], ecx 00278 2b c1 sub eax, ecx 0027a 48 03 f0 add rsi, rax $LN102@stbi__crea: ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above 0027d 8b 44 24 38 mov eax, DWORD PTR stride$1$[rsp] ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; 00281 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:__ImageBase 00288 4c 8b fe mov r15, rsi 0028b 4c 2b f8 sub r15, rax 0028e 85 d2 test edx, edx 00290 75 09 jne SHORT $LN104@stbi__crea 00292 45 0f b6 94 0a 00 00 00 00 movzx r10d, BYTE PTR first_row_filter[r10+rcx] $LN104@stbi__crea: ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { 0029b 4d 85 f6 test r14, r14 0029e 0f 8e 31 01 00 00 jle $LN6@stbi__crea 002a4 49 8b ff mov rdi, r15 002a7 4c 8b de mov r11, rsi 002aa 48 2b fb sub rdi, rbx 002ad 48 8b d3 mov rdx, rbx 002b0 4c 2b db sub r11, rbx 002b3 4d 8b ce mov r9, r14 $LL7@stbi__crea: ; 4200 : switch (filter) { 002b6 4c 8b c2 mov r8, rdx 002b9 41 83 fa 06 cmp r10d, 6 002bd 77 0f ja SHORT $LN5@stbi__crea 002bf 49 63 c2 movsxd rax, r10d 002c2 8b 84 81 00 00 00 00 mov eax, DWORD PTR $LN398@stbi__crea[rcx+rax*4] 002c9 48 03 c1 add rax, rcx 002cc ff e0 jmp rax $LN5@stbi__crea: ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { 002ce 48 ff c2 inc rdx 002d1 49 83 e9 01 sub r9, 1 002d5 0f 84 ea 00 00 00 je $LN492@stbi__crea 002db 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:__ImageBase 002e2 eb d2 jmp SHORT $LL7@stbi__crea 002e4 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL406@stbi__crea: ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; 002f0 0f b6 02 movzx eax, BYTE PTR [rdx] 002f3 48 ff c2 inc rdx 002f6 43 88 04 03 mov BYTE PTR [r11+r8], al 002fa 49 83 e9 01 sub r9, 1 002fe 0f 84 c1 00 00 00 je $LN492@stbi__crea ; 4200 : switch (filter) { 00304 4c 8b c2 mov r8, rdx 00307 eb e7 jmp SHORT $LL406@stbi__crea 00309 0f 1f 80 00 00 00 00 npad 7 $LL407@stbi__crea: ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; 00310 0f b6 02 movzx eax, BYTE PTR [rdx] 00313 48 ff c2 inc rdx 00316 43 88 04 03 mov BYTE PTR [r11+r8], al 0031a 49 83 e9 01 sub r9, 1 0031e 0f 84 a1 00 00 00 je $LN492@stbi__crea ; 4200 : switch (filter) { 00324 4c 8b c2 mov r8, rdx 00327 eb e7 jmp SHORT $LL407@stbi__crea 00329 0f 1f 80 00 00 00 00 npad 7 $LL447@stbi__crea: ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; 00330 42 0f b6 04 07 movzx eax, BYTE PTR [rdi+r8] 00335 02 02 add al, BYTE PTR [rdx] 00337 48 ff c2 inc rdx 0033a 43 88 04 03 mov BYTE PTR [r11+r8], al 0033e 49 83 e9 01 sub r9, 1 00342 0f 84 7d 00 00 00 je $LN492@stbi__crea ; 4200 : switch (filter) { 00348 4c 8b c2 mov r8, rdx 0034b eb e3 jmp SHORT $LL447@stbi__crea 0034d 0f 1f 00 npad 3 $LL448@stbi__crea: ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; 00350 42 0f b6 04 07 movzx eax, BYTE PTR [rdi+r8] 00355 d0 e8 shr al, 1 00357 02 02 add al, BYTE PTR [rdx] 00359 48 ff c2 inc rdx 0035c 43 88 04 03 mov BYTE PTR [r11+r8], al 00360 49 83 e9 01 sub r9, 1 00364 74 5f je SHORT $LN492@stbi__crea ; 4200 : switch (filter) { 00366 4c 8b c2 mov r8, rdx 00369 eb e5 jmp SHORT $LL448@stbi__crea 0036b 0f 1f 44 00 00 npad 5 $LL449@stbi__crea: ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; 00370 42 0f b6 04 07 movzx eax, BYTE PTR [rdi+r8] 00375 33 c9 xor ecx, ecx 00377 84 c0 test al, al 00379 0f 45 c8 cmovne ecx, eax 0037c 02 0a add cl, BYTE PTR [rdx] 0037e 48 ff c2 inc rdx 00381 43 88 0c 03 mov BYTE PTR [r11+r8], cl 00385 49 83 e9 01 sub r9, 1 00389 74 3a je SHORT $LN492@stbi__crea ; 4200 : switch (filter) { 0038b 4c 8b c2 mov r8, rdx 0038e eb e0 jmp SHORT $LL449@stbi__crea $LL450@stbi__crea: ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; 00390 0f b6 02 movzx eax, BYTE PTR [rdx] 00393 48 ff c2 inc rdx 00396 43 88 04 03 mov BYTE PTR [r11+r8], al 0039a 49 83 e9 01 sub r9, 1 0039e 74 25 je SHORT $LN492@stbi__crea ; 4200 : switch (filter) { 003a0 4c 8b c2 mov r8, rdx 003a3 eb eb jmp SHORT $LL450@stbi__crea 003a5 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL451@stbi__crea: ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; 003b0 0f b6 02 movzx eax, BYTE PTR [rdx] 003b3 48 ff c2 inc rdx 003b6 43 88 04 03 mov BYTE PTR [r11+r8], al 003ba 49 83 e9 01 sub r9, 1 003be 74 05 je SHORT $LN492@stbi__crea ; 4200 : switch (filter) { 003c0 4c 8b c2 mov r8, rdx 003c3 eb eb jmp SHORT $LL451@stbi__crea $LN492@stbi__crea: ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { 003c5 4c 8b 44 24 28 mov r8, QWORD PTR $T13[rsp] 003ca 45 33 c9 xor r9d, r9d 003cd 44 8b 9c 24 f0 00 00 00 mov r11d, DWORD PTR img_n$1$[rsp] $LN6@stbi__crea: 003d5 8b 84 24 20 01 00 00 mov eax, DWORD PTR depth$[rsp] 003dc 83 f8 08 cmp eax, 8 003df 75 2b jne SHORT $LN112@stbi__crea ; 4212 : if (img_n != out_n) 003e1 48 63 84 24 08 01 00 00 movsxd rax, DWORD PTR out_n$[rsp] 003e9 44 3b d8 cmp r11d, eax 003ec 74 05 je SHORT $LN114@stbi__crea ; 4213 : cur[img_n] = 255; // first pixel 003ee 41 c6 04 30 ff mov BYTE PTR [r8+rsi], 255 ; 000000ffH $LN114@stbi__crea: ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; 003f3 49 03 d8 add rbx, r8 003f6 4e 8d 1c 38 lea r11, QWORD PTR [rax+r15] 003fa 48 03 c6 add rax, rsi 003fd 4c 89 5c 24 58 mov QWORD PTR prior$4$[rsp], r11 00402 48 89 44 24 40 mov QWORD PTR cur$8$[rsp], rax 00407 4c 8b c3 mov r8, rbx ; 4217 : } 0040a eb 59 jmp SHORT $LN383@stbi__crea $LN112@stbi__crea: ; 4218 : else if (depth == 16) { 0040c 83 f8 10 cmp eax, 16 0040f 75 2e jne SHORT $LN115@stbi__crea ; 4219 : if (img_n != out_n) { 00411 44 3b 9c 24 08 01 00 00 cmp r11d, DWORD PTR out_n$[rsp] 00419 74 07 je SHORT $LN117@stbi__crea ; 4220 : cur[filter_bytes] = 255; // first pixel top byte 0041b 66 41 c7 04 36 ff ff mov WORD PTR [r14+rsi], 65535 ; 0000ffffH $LN117@stbi__crea: ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; 00422 49 63 c4 movsxd rax, r12d ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; 00425 4f 8d 1c 2f lea r11, QWORD PTR [r15+r13] 00429 48 03 d8 add rbx, rax 0042c 4c 89 5c 24 58 mov QWORD PTR prior$4$[rsp], r11 00431 4a 8d 04 2e lea rax, QWORD PTR [rsi+r13] 00435 4c 8b c3 mov r8, rbx 00438 48 89 44 24 40 mov QWORD PTR cur$8$[rsp], rax ; 4226 : } 0043d eb 26 jmp SHORT $LN383@stbi__crea $LN115@stbi__crea: ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { 0043f 48 ff c3 inc rbx 00442 4d 8d 5f 01 lea r11, QWORD PTR [r15+1] 00446 83 bc 24 20 01 00 00 08 cmp DWORD PTR depth$[rsp], 8 0044e 48 8d 46 01 lea rax, QWORD PTR [rsi+1] 00452 4c 8b c3 mov r8, rbx 00455 4c 89 5c 24 58 mov QWORD PTR prior$4$[rsp], r11 0045a 48 89 44 24 40 mov QWORD PTR cur$8$[rsp], rax 0045f 0f 8c 2f 05 00 00 jl $LN120@stbi__crea $LN383@stbi__crea: 00465 8b 8c 24 f0 00 00 00 mov ecx, DWORD PTR img_n$1$[rsp] 0046c 3b 8c 24 08 01 00 00 cmp ecx, DWORD PTR out_n$[rsp] 00473 0f 84 1b 05 00 00 je $LN120@stbi__crea ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { 00479 41 83 fa 06 cmp r10d, 6 0047d 0f 87 d3 04 00 00 ja $LN494@stbi__crea 00483 49 63 ca movsxd rcx, r10d 00486 49 8b d8 mov rbx, r8 00489 4c 8d 15 00 00 00 00 lea r10, OFFSET FLAT:__ImageBase 00490 41 8b 94 8a 00 00 00 00 mov edx, DWORD PTR $LN397@stbi__crea[r10+rcx*4] 00498 49 03 d2 add rdx, r10 0049b ff e2 jmp rdx $LN128@stbi__crea: ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; 0049d 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 004a4 8d 4a ff lea ecx, DWORD PTR [rdx-1] 004a7 83 f9 01 cmp ecx, 1 004aa 0f 82 ad 04 00 00 jb $LN69@stbi__crea 004b0 4d 63 dc movsxd r11, r12d 004b3 44 8b d1 mov r10d, ecx $LL34@stbi__crea: 004b6 4d 85 f6 test r14, r14 004b9 7e 26 jle SHORT $LN32@stbi__crea 004bb 4c 8b cb mov r9, rbx 004be 48 8b d0 mov rdx, rax 004c1 4c 2b c8 sub r9, rax 004c4 4d 8b c6 mov r8, r14 004c7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL292@stbi__crea: 004d0 42 0f b6 0c 0a movzx ecx, BYTE PTR [rdx+r9] 004d5 88 0a mov BYTE PTR [rdx], cl 004d7 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 004db 49 83 e8 01 sub r8, 1 004df 75 ef jne SHORT $LL292@stbi__crea $LN32@stbi__crea: 004e1 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 004e6 49 03 db add rbx, r11 004e9 49 03 c5 add rax, r13 004ec 49 83 ea 01 sub r10, 1 004f0 75 c4 jne SHORT $LL34@stbi__crea 004f2 e9 5f 04 00 00 jmp $LN494@stbi__crea $LN129@stbi__crea: ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; 004f7 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 004fe 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00501 83 f9 01 cmp ecx, 1 00504 0f 82 53 04 00 00 jb $LN69@stbi__crea 0050a 49 63 fc movsxd rdi, r12d 0050d 44 8b d9 mov r11d, ecx $LL40@stbi__crea: 00510 4d 85 f6 test r14, r14 00513 7e 30 jle SHORT $LN38@stbi__crea 00515 4c 8b c0 mov r8, rax 00518 4c 8b d0 mov r10, rax 0051b 4d 2b c5 sub r8, r13 0051e 48 8b d3 mov rdx, rbx 00521 4c 2b c3 sub r8, rbx 00524 4d 8b ce mov r9, r14 00527 4c 2b d3 sub r10, rbx 0052a 66 0f 1f 44 00 00 npad 6 $LL43@stbi__crea: 00530 42 0f b6 0c 02 movzx ecx, BYTE PTR [rdx+r8] 00535 02 0a add cl, BYTE PTR [rdx] 00537 41 88 0c 12 mov BYTE PTR [r10+rdx], cl 0053b 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 0053f 49 83 e9 01 sub r9, 1 00543 75 eb jne SHORT $LL43@stbi__crea $LN38@stbi__crea: 00545 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 0054a 48 03 df add rbx, rdi 0054d 49 03 c5 add rax, r13 00550 49 83 eb 01 sub r11, 1 00554 75 ba jne SHORT $LL40@stbi__crea 00556 e9 fb 03 00 00 jmp $LN494@stbi__crea $LN130@stbi__crea: ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; 0055b 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 00562 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00565 83 f9 01 cmp ecx, 1 00568 0f 82 ef 03 00 00 jb $LN69@stbi__crea 0056e 49 63 ec movsxd rbp, r12d 00571 8b f1 mov esi, ecx $LL46@stbi__crea: 00573 4d 8b c1 mov r8, r9 00576 45 85 e4 test r12d, r12d 00579 0f 8e 32 01 00 00 jle $LN295@stbi__crea 0057f 41 83 fc 08 cmp r12d, 8 00583 0f 82 28 01 00 00 jb $LN295@stbi__crea 00589 41 8d 4c 24 ff lea ecx, DWORD PTR [r12-1] 0058e 48 63 d1 movsxd rdx, ecx 00591 48 8d 0c 1a lea rcx, QWORD PTR [rdx+rbx] 00595 4c 8d 0c 02 lea r9, QWORD PTR [rdx+rax] 00599 48 3b c1 cmp rax, rcx 0059c 77 09 ja SHORT $LN298@stbi__crea 0059e 4c 3b cb cmp r9, rbx 005a1 0f 83 0a 01 00 00 jae $LN295@stbi__crea $LN298@stbi__crea: 005a7 4a 8d 0c 1a lea rcx, QWORD PTR [rdx+r11] 005ab 48 3b c1 cmp rax, rcx 005ae 77 09 ja SHORT $LN299@stbi__crea 005b0 4d 3b cb cmp r9, r11 005b3 0f 83 f8 00 00 00 jae $LN295@stbi__crea $LN299@stbi__crea: 005b9 41 83 fc 40 cmp r12d, 64 ; 00000040H 005bd 0f 82 9c 00 00 00 jb $LN382@stbi__crea 005c3 41 8b d4 mov edx, r12d 005c6 81 e2 3f 00 00 80 and edx, -2147483585 ; ffffffff8000003fH 005cc 7d 07 jge SHORT $LN396@stbi__crea 005ce ff ca dec edx 005d0 83 ca c0 or edx, -64 ; ffffffffffffffc0H 005d3 ff c2 inc edx $LN396@stbi__crea: 005d5 41 8b cc mov ecx, r12d 005d8 2b ca sub ecx, edx 005da 49 8b d3 mov rdx, r11 005dd 4c 63 d1 movsxd r10, ecx 005e0 48 2b d3 sub rdx, rbx 005e3 48 8d 4b 10 lea rcx, QWORD PTR [rbx+16] 005e7 4c 8b c8 mov r9, rax 005ea 4c 2b cb sub r9, rbx 005ed 0f 1f 00 npad 3 $LL49@stbi__crea: 005f0 f3 0f 6f 41 f0 movdqu xmm0, XMMWORD PTR [rcx-16] 005f5 49 83 c0 40 add r8, 64 ; 00000040H 005f9 f3 0f 6f 4c 11 f0 movdqu xmm1, XMMWORD PTR [rcx+rdx-16] 005ff f3 0f 6f 11 movdqu xmm2, XMMWORD PTR [rcx] 00603 48 8d 49 40 lea rcx, QWORD PTR [rcx+64] 00607 66 0f fc c8 paddb xmm1, xmm0 0060b f3 0f 6f 44 11 c0 movdqu xmm0, XMMWORD PTR [rcx+rdx-64] 00611 f3 41 0f 7f 4c 09 b0 movdqu XMMWORD PTR [r9+rcx-80], xmm1 00618 66 0f fc d0 paddb xmm2, xmm0 0061c f3 0f 6f 41 d0 movdqu xmm0, XMMWORD PTR [rcx-48] 00621 f3 0f 6f 4c 11 d0 movdqu xmm1, XMMWORD PTR [rcx+rdx-48] 00627 f3 41 0f 7f 54 09 c0 movdqu XMMWORD PTR [r9+rcx-64], xmm2 0062e 66 0f fc c8 paddb xmm1, xmm0 00632 f3 0f 6f 41 e0 movdqu xmm0, XMMWORD PTR [rcx-32] 00637 f3 0f 6f 54 11 e0 movdqu xmm2, XMMWORD PTR [rcx+rdx-32] 0063d f3 41 0f 7f 4c 09 d0 movdqu XMMWORD PTR [r9+rcx-48], xmm1 00644 66 0f fc d0 paddb xmm2, xmm0 00648 f3 41 0f 7f 54 09 e0 movdqu XMMWORD PTR [r9+rcx-32], xmm2 0064f 4d 3b c2 cmp r8, r10 00652 7c 9c jl SHORT $LL49@stbi__crea 00654 41 8b cc mov ecx, r12d 00657 80 e1 3f and cl, 63 ; 0000003fH 0065a 80 f9 08 cmp cl, 8 0065d 72 52 jb SHORT $LN295@stbi__crea $LN382@stbi__crea: 0065f 41 8b d4 mov edx, r12d 00662 81 e2 07 00 00 80 and edx, -2147483641 ; ffffffff80000007H 00668 7d 07 jge SHORT $LN395@stbi__crea 0066a ff ca dec edx 0066c 83 ca f8 or edx, -8 0066f ff c2 inc edx $LN395@stbi__crea: 00671 41 8b cc mov ecx, r12d 00674 2b ca sub ecx, edx 00676 49 8b d3 mov rdx, r11 00679 4c 63 d1 movsxd r10, ecx 0067c 48 2b d3 sub rdx, rbx 0067f 49 8d 0c 18 lea rcx, QWORD PTR [r8+rbx] 00683 4c 8b c8 mov r9, rax 00686 4c 2b cb sub r9, rbx 00689 0f 1f 80 00 00 00 00 npad 7 $LL296@stbi__crea: 00690 f3 0f 7e 0c 11 movq xmm1, QWORD PTR [rcx+rdx] 00695 49 83 c0 08 add r8, 8 00699 f3 0f 7e 01 movq xmm0, QWORD PTR [rcx] 0069d 48 8d 49 08 lea rcx, QWORD PTR [rcx+8] 006a1 66 0f fc c8 paddb xmm1, xmm0 006a5 66 41 0f d6 4c 09 f8 movq QWORD PTR [r9+rcx-8], xmm1 006ac 4d 3b c2 cmp r8, r10 006af 7c df jl SHORT $LL296@stbi__crea $LN295@stbi__crea: 006b1 4d 3b c6 cmp r8, r14 006b4 7d 2e jge SHORT $LN44@stbi__crea 006b6 4d 8b d3 mov r10, r11 006b9 49 8d 14 18 lea rdx, QWORD PTR [r8+rbx] 006bd 48 8b f8 mov rdi, rax 006c0 4c 2b d3 sub r10, rbx 006c3 48 2b fb sub rdi, rbx 006c6 4d 8b ce mov r9, r14 006c9 4d 2b c8 sub r9, r8 006cc 0f 1f 40 00 npad 4 $LL294@stbi__crea: 006d0 42 0f b6 0c 12 movzx ecx, BYTE PTR [rdx+r10] 006d5 02 0a add cl, BYTE PTR [rdx] 006d7 88 0c 17 mov BYTE PTR [rdi+rdx], cl 006da 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 006de 49 83 e9 01 sub r9, 1 006e2 75 ec jne SHORT $LL294@stbi__crea $LN44@stbi__crea: 006e4 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 006e9 48 03 dd add rbx, rbp 006ec 49 03 c5 add rax, r13 006ef 4d 03 dd add r11, r13 006f2 41 b9 00 00 00 00 mov r9d, 0 006f8 48 83 ee 01 sub rsi, 1 006fc 0f 85 71 fe ff ff jne $LL46@stbi__crea 00702 48 8b 6c 24 60 mov rbp, QWORD PTR cur$9$[rsp] 00707 e9 4a 02 00 00 jmp $LN494@stbi__crea $LN131@stbi__crea: ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; 0070c 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 00713 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00716 83 f9 01 cmp ecx, 1 00719 0f 82 3e 02 00 00 jb $LN69@stbi__crea 0071f 4d 63 fc movsxd r15, r12d 00722 8b e9 mov ebp, ecx $LL52@stbi__crea: 00724 4d 85 f6 test r14, r14 00727 7e 48 jle SHORT $LN50@stbi__crea 00729 4c 8b c8 mov r9, rax 0072c 48 8b fb mov rdi, rbx 0072f 4d 2b cd sub r9, r13 00732 49 2b fb sub rdi, r11 00735 4d 2b cb sub r9, r11 00738 48 8b f0 mov rsi, rax 0073b 49 2b f3 sub rsi, r11 0073e 4d 8b c3 mov r8, r11 00741 4d 8b d6 mov r10, r14 00744 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL55@stbi__crea: 00750 43 0f b6 14 08 movzx edx, BYTE PTR [r8+r9] 00755 41 0f b6 08 movzx ecx, BYTE PTR [r8] 00759 4d 8d 40 01 lea r8, QWORD PTR [r8+1] 0075d 03 d1 add edx, ecx 0075f d1 ea shr edx, 1 00761 42 02 54 07 ff add dl, BYTE PTR [rdi+r8-1] 00766 42 88 54 06 ff mov BYTE PTR [rsi+r8-1], dl 0076b 49 83 ea 01 sub r10, 1 0076f 75 df jne SHORT $LL55@stbi__crea $LN50@stbi__crea: 00771 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 00776 49 03 df add rbx, r15 00779 49 03 c5 add rax, r13 0077c 4d 03 dd add r11, r13 0077f 48 83 ed 01 sub rbp, 1 00783 75 9f jne SHORT $LL52@stbi__crea 00785 48 8b 6c 24 60 mov rbp, QWORD PTR cur$9$[rsp] 0078a e9 c7 01 00 00 jmp $LN494@stbi__crea $LN132@stbi__crea: ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; 0078f 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 00796 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00799 83 f9 01 cmp ecx, 1 0079c 0f 82 bb 01 00 00 jb $LN69@stbi__crea 007a2 49 63 d4 movsxd rdx, r12d 007a5 48 89 94 24 90 00 00 00 mov QWORD PTR tv5835[rsp], rdx 007ad 48 89 4c 24 70 mov QWORD PTR tv5788[rsp], rcx $LL58@stbi__crea: 007b2 4d 85 f6 test r14, r14 007b5 0f 8e aa 00 00 00 jle $LN56@stbi__crea 007bb 49 8b cb mov rcx, r11 007be 4c 8b d0 mov r10, rax 007c1 48 2b c8 sub rcx, rax 007c4 4d 2b d5 sub r10, r13 007c7 48 89 8c 24 80 00 00 00 mov QWORD PTR tv5731[rsp], rcx 007cf 4d 8b e6 mov r12, r14 007d2 4c 8b b4 24 80 00 00 00 mov r14, QWORD PTR tv5731[rsp] 007da 49 8b cd mov rcx, r13 007dd 48 2b c8 sub rcx, rax 007e0 4a 8d 04 19 lea rax, QWORD PTR [rcx+r11] 007e4 4c 8d 1c 0b lea r11, QWORD PTR [rbx+rcx] 007e8 0f 1f 84 00 00 00 00 00 npad 8 $LL61@stbi__crea: 007f0 45 0f b6 0a movzx r9d, BYTE PTR [r10] 007f4 43 0f b6 2c 32 movzx ebp, BYTE PTR [r10+r14] ; 4141 : int p = a + b - c; 007f9 41 8b d1 mov edx, r9d ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; 007fc 46 0f b6 3c 10 movzx r15d, BYTE PTR [rax+r10] ; 4141 : int p = a + b - c; 00801 2b d5 sub edx, ebp ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); 00803 8b f2 mov esi, edx 00805 45 8d 04 17 lea r8d, DWORD PTR [r15+rdx] 00809 41 8b c8 mov ecx, r8d 0080c 41 2b c9 sub ecx, r9d 0080f 8b f9 mov edi, ecx 00811 f7 df neg edi 00813 0f 48 f9 cmovs edi, ecx 00816 f7 de neg esi 00818 0f 48 f2 cmovs esi, edx ; 4144 : int pc = abs(p - c); 0081b 44 2b c5 sub r8d, ebp 0081e 41 8b c8 mov ecx, r8d 00821 f7 d9 neg ecx 00823 41 0f 48 c8 cmovs ecx, r8d ; 4145 : if (pa <= pb && pa <= pc) return a; 00827 3b fe cmp edi, esi 00829 7f 04 jg SHORT $LN223@stbi__crea 0082b 3b f9 cmp edi, ecx 0082d 7e 09 jle SHORT $LN224@stbi__crea $LN223@stbi__crea: ; 4146 : if (pb <= pc) return b; 0082f 3b f1 cmp esi, ecx 00831 44 8b cd mov r9d, ebp 00834 45 0f 4e cf cmovle r9d, r15d $LN224@stbi__crea: ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; 00838 47 02 0c 13 add r9b, BYTE PTR [r11+r10] 0083c 47 88 0c 2a mov BYTE PTR [r10+r13], r9b 00840 49 ff c2 inc r10 00843 49 83 ec 01 sub r12, 1 00847 75 a7 jne SHORT $LL61@stbi__crea 00849 48 8b 44 24 40 mov rax, QWORD PTR cur$8$[rsp] 0084e 4c 8b 5c 24 58 mov r11, QWORD PTR prior$4$[rsp] 00853 4c 8b 74 24 68 mov r14, QWORD PTR $T15[rsp] 00858 48 8b 4c 24 70 mov rcx, QWORD PTR tv5788[rsp] 0085d 48 8b 94 24 90 00 00 00 mov rdx, QWORD PTR tv5835[rsp] $LN56@stbi__crea: 00865 4d 03 dd add r11, r13 00868 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 0086d 49 03 c5 add rax, r13 00870 4c 89 5c 24 58 mov QWORD PTR prior$4$[rsp], r11 00875 48 03 da add rbx, rdx 00878 48 89 44 24 40 mov QWORD PTR cur$8$[rsp], rax 0087d 48 83 e9 01 sub rcx, 1 00881 48 89 4c 24 70 mov QWORD PTR tv5788[rsp], rcx 00886 0f 85 26 ff ff ff jne $LL58@stbi__crea 0088c 48 8b 6c 24 60 mov rbp, QWORD PTR cur$9$[rsp] 00891 e9 c0 00 00 00 jmp $LN494@stbi__crea $LN133@stbi__crea: ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; 00896 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 0089d 8d 4a ff lea ecx, DWORD PTR [rdx-1] 008a0 83 f9 01 cmp ecx, 1 008a3 0f 82 b4 00 00 00 jb $LN69@stbi__crea 008a9 49 63 fc movsxd rdi, r12d 008ac 44 8b d9 mov r11d, ecx 008af 90 npad 1 $LL64@stbi__crea: 008b0 4d 85 f6 test r14, r14 008b3 7e 34 jle SHORT $LN62@stbi__crea 008b5 4c 8b c0 mov r8, rax 008b8 4c 8b d0 mov r10, rax 008bb 4d 2b c5 sub r8, r13 008be 48 8b d3 mov rdx, rbx 008c1 4c 2b c3 sub r8, rbx 008c4 4d 8b ce mov r9, r14 008c7 4c 2b d3 sub r10, rbx 008ca 66 0f 1f 44 00 00 npad 6 $LL67@stbi__crea: 008d0 42 0f b6 0c 02 movzx ecx, BYTE PTR [rdx+r8] 008d5 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 008d9 d0 e9 shr cl, 1 008db 02 4a ff add cl, BYTE PTR [rdx-1] 008de 41 88 4c 12 ff mov BYTE PTR [r10+rdx-1], cl 008e3 49 83 e9 01 sub r9, 1 008e7 75 e7 jne SHORT $LL67@stbi__crea $LN62@stbi__crea: 008e9 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 008ee 48 03 df add rbx, rdi 008f1 49 03 c5 add rax, r13 008f4 49 83 eb 01 sub r11, 1 008f8 75 b6 jne SHORT $LL64@stbi__crea 008fa eb 5a jmp SHORT $LN494@stbi__crea $LN134@stbi__crea: ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; 008fc 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] 00903 8d 4a ff lea ecx, DWORD PTR [rdx-1] 00906 83 f9 01 cmp ecx, 1 00909 72 52 jb SHORT $LN69@stbi__crea 0090b 49 63 fc movsxd rdi, r12d 0090e 44 8b d9 mov r11d, ecx $LL70@stbi__crea: 00911 4d 85 f6 test r14, r14 00914 7e 2f jle SHORT $LN68@stbi__crea 00916 4c 8b c0 mov r8, rax 00919 4c 8b d0 mov r10, rax 0091c 4d 2b c5 sub r8, r13 0091f 48 8b d3 mov rdx, rbx 00922 4c 2b c3 sub r8, rbx 00925 4d 8b ce mov r9, r14 00928 4c 2b d3 sub r10, rbx 0092b 0f 1f 44 00 00 npad 5 $LL73@stbi__crea: ; 4145 : if (pa <= pb && pa <= pc) return a; 00930 42 0f b6 0c 02 movzx ecx, BYTE PTR [rdx+r8] ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; 00935 02 0a add cl, BYTE PTR [rdx] 00937 41 88 0c 12 mov BYTE PTR [r10+rdx], cl 0093b 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 0093f 49 83 e9 01 sub r9, 1 00943 75 eb jne SHORT $LL73@stbi__crea $LN68@stbi__crea: 00945 41 c6 04 06 ff mov BYTE PTR [r14+rax], 255 ; 000000ffH 0094a 48 03 df add rbx, rdi 0094d 49 03 c5 add rax, r13 00950 49 83 eb 01 sub r11, 1 00954 75 bb jne SHORT $LL70@stbi__crea $LN494@stbi__crea: ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { 00956 8b 94 24 10 01 00 00 mov edx, DWORD PTR x$[rsp] $LN69@stbi__crea: 0095d 83 bc 24 20 01 00 00 10 cmp DWORD PTR depth$[rsp], 16 00965 0f 85 4f 03 00 00 jne $LN2@stbi__crea ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { 0096b 85 d2 test edx, edx 0096d 0f 84 47 03 00 00 je $LN2@stbi__crea ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again 00973 8b c2 mov eax, edx 00975 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL76@stbi__crea: ; 4274 : cur[filter_bytes + 1] = 255; 00980 41 c6 44 2e 01 ff mov BYTE PTR [r14+rbp+1], 255 ; 000000ffH 00986 49 03 ed add rbp, r13 00989 48 83 e8 01 sub rax, 1 0098d 75 f1 jne SHORT $LL76@stbi__crea ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); 0098f e9 26 03 00 00 jmp $LN2@stbi__crea $LN120@stbi__crea: ; 4235 : int nk = (width - 1) * filter_bytes; 00994 8b 74 24 48 mov esi, DWORD PTR width$1$[rsp] 00998 ff ce dec esi 0099a 41 0f af f4 imul esi, r12d 0099e 89 74 24 40 mov DWORD PTR nk$1$[rsp], esi ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { 009a2 41 83 fa 06 cmp r10d, 6 009a6 0f 87 08 03 00 00 ja $LN28@stbi__crea 009ac 49 63 ca movsxd rcx, r10d 009af 4c 8d 15 00 00 00 00 lea r10, OFFSET FLAT:__ImageBase 009b6 4c 63 c6 movsxd r8, esi 009b9 41 8b 94 8a 00 00 00 00 mov edx, DWORD PTR $LN394@stbi__crea[r10+rcx*4] 009c1 49 03 d2 add rdx, r10 009c4 ff e2 jmp rdx $LN121@stbi__crea: ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; 009c6 48 8b d3 mov rdx, rbx 009c9 48 8b c8 mov rcx, rax 009cc e8 00 00 00 00 call memcpy 009d1 e9 de 02 00 00 jmp $LN28@stbi__crea $LN122@stbi__crea: ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; 009d6 85 f6 test esi, esi 009d8 0f 8e d6 02 00 00 jle $LN28@stbi__crea 009de 4c 8b c8 mov r9, rax 009e1 48 8b d3 mov rdx, rbx 009e4 4d 2b ce sub r9, r14 009e7 4c 2b cb sub r9, rbx 009ea 48 2b c3 sub rax, rbx 009ed 0f 1f 00 npad 3 $LL14@stbi__crea: 009f0 42 0f b6 0c 0a movzx ecx, BYTE PTR [rdx+r9] 009f5 02 0a add cl, BYTE PTR [rdx] 009f7 88 0c 10 mov BYTE PTR [rax+rdx], cl 009fa 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 009fe 49 83 e8 01 sub r8, 1 00a02 75 ec jne SHORT $LL14@stbi__crea 00a04 e9 ab 02 00 00 jmp $LN28@stbi__crea $LN123@stbi__crea: ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; 00a09 85 f6 test esi, esi 00a0b 0f 8e 30 01 00 00 jle $LN301@stbi__crea 00a11 83 fe 08 cmp esi, 8 00a14 0f 82 27 01 00 00 jb $LN301@stbi__crea 00a1a 8d 4e ff lea ecx, DWORD PTR [rsi-1] 00a1d 45 33 c9 xor r9d, r9d 00a20 48 63 d1 movsxd rdx, ecx 00a23 48 8d 0c 1a lea rcx, QWORD PTR [rdx+rbx] 00a27 4c 8d 14 02 lea r10, QWORD PTR [rdx+rax] 00a2b 48 3b c1 cmp rax, rcx 00a2e 77 09 ja SHORT $LN304@stbi__crea 00a30 4c 3b d3 cmp r10, rbx 00a33 0f 83 08 01 00 00 jae $LN301@stbi__crea $LN304@stbi__crea: 00a39 4a 8d 0c 1a lea rcx, QWORD PTR [rdx+r11] 00a3d 48 3b c1 cmp rax, rcx 00a40 77 09 ja SHORT $LN305@stbi__crea 00a42 4d 3b d3 cmp r10, r11 00a45 0f 83 f6 00 00 00 jae $LN301@stbi__crea $LN305@stbi__crea: 00a4b 83 fe 40 cmp esi, 64 ; 00000040H 00a4e 0f 82 9a 00 00 00 jb $LN303@stbi__crea 00a54 8b d6 mov edx, esi 00a56 81 e2 3f 00 00 80 and edx, -2147483585 ; ffffffff8000003fH 00a5c 7d 07 jge SHORT $LN393@stbi__crea 00a5e ff ca dec edx 00a60 83 ca c0 or edx, -64 ; ffffffffffffffc0H 00a63 ff c2 inc edx $LN393@stbi__crea: 00a65 8b ce mov ecx, esi 00a67 2b ca sub ecx, edx 00a69 49 8b d3 mov rdx, r11 00a6c 48 63 f9 movsxd rdi, ecx 00a6f 48 2b d3 sub rdx, rbx 00a72 48 8d 4b 10 lea rcx, QWORD PTR [rbx+16] 00a76 4c 8b d0 mov r10, rax 00a79 4c 2b d3 sub r10, rbx 00a7c 0f 1f 40 00 npad 4 $LL17@stbi__crea: 00a80 f3 0f 6f 41 f0 movdqu xmm0, XMMWORD PTR [rcx-16] 00a85 49 83 c1 40 add r9, 64 ; 00000040H 00a89 f3 0f 6f 4c 11 f0 movdqu xmm1, XMMWORD PTR [rcx+rdx-16] 00a8f f3 0f 6f 14 11 movdqu xmm2, XMMWORD PTR [rcx+rdx] 00a94 48 8d 49 40 lea rcx, QWORD PTR [rcx+64] 00a98 66 0f fc c8 paddb xmm1, xmm0 00a9c f3 0f 6f 41 c0 movdqu xmm0, XMMWORD PTR [rcx-64] 00aa1 f3 41 0f 7f 4c 0a b0 movdqu XMMWORD PTR [r10+rcx-80], xmm1 00aa8 66 0f fc d0 paddb xmm2, xmm0 00aac f3 0f 6f 41 d0 movdqu xmm0, XMMWORD PTR [rcx-48] 00ab1 f3 0f 6f 4c 11 d0 movdqu xmm1, XMMWORD PTR [rcx+rdx-48] 00ab7 f3 41 0f 7f 54 0a c0 movdqu XMMWORD PTR [r10+rcx-64], xmm2 00abe 66 0f fc c8 paddb xmm1, xmm0 00ac2 f3 0f 6f 41 e0 movdqu xmm0, XMMWORD PTR [rcx-32] 00ac7 f3 0f 6f 54 11 e0 movdqu xmm2, XMMWORD PTR [rcx+rdx-32] 00acd f3 41 0f 7f 4c 0a d0 movdqu XMMWORD PTR [r10+rcx-48], xmm1 00ad4 66 0f fc d0 paddb xmm2, xmm0 00ad8 f3 41 0f 7f 54 0a e0 movdqu XMMWORD PTR [r10+rcx-32], xmm2 00adf 4c 3b cf cmp r9, rdi 00ae2 7c 9c jl SHORT $LL17@stbi__crea 00ae4 8b ce mov ecx, esi 00ae6 80 e1 3f and cl, 63 ; 0000003fH 00ae9 80 f9 08 cmp cl, 8 00aec 72 53 jb SHORT $LN301@stbi__crea $LN303@stbi__crea: 00aee 8b d6 mov edx, esi 00af0 81 e2 07 00 00 80 and edx, -2147483641 ; ffffffff80000007H 00af6 7d 07 jge SHORT $LN392@stbi__crea 00af8 ff ca dec edx 00afa 83 ca f8 or edx, -8 00afd ff c2 inc edx $LN392@stbi__crea: 00aff 8b ce mov ecx, esi 00b01 2b ca sub ecx, edx 00b03 49 8b d3 mov rdx, r11 00b06 48 63 f9 movsxd rdi, ecx 00b09 48 2b d3 sub rdx, rbx 00b0c 49 8d 0c 19 lea rcx, QWORD PTR [r9+rbx] 00b10 4c 8b d0 mov r10, rax 00b13 4c 2b d3 sub r10, rbx 00b16 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL302@stbi__crea: 00b20 f3 0f 7e 0c 11 movq xmm1, QWORD PTR [rcx+rdx] 00b25 49 83 c1 08 add r9, 8 00b29 f3 0f 7e 01 movq xmm0, QWORD PTR [rcx] 00b2d 48 8d 49 08 lea rcx, QWORD PTR [rcx+8] 00b31 66 0f fc c8 paddb xmm1, xmm0 00b35 66 41 0f d6 4c 0a f8 movq QWORD PTR [r10+rcx-8], xmm1 00b3c 4c 3b cf cmp r9, rdi 00b3f 7c df jl SHORT $LL302@stbi__crea $LN301@stbi__crea: 00b41 4d 3b c8 cmp r9, r8 00b44 0f 8d 6a 01 00 00 jge $LN28@stbi__crea 00b4a 4c 2b db sub r11, rbx 00b4d 49 8d 14 19 lea rdx, QWORD PTR [r9+rbx] 00b51 48 2b c3 sub rax, rbx 00b54 4d 2b c1 sub r8, r9 00b57 66 0f 1f 84 00 00 00 00 00 npad 9 $LL300@stbi__crea: 00b60 42 0f b6 0c 1a movzx ecx, BYTE PTR [rdx+r11] 00b65 02 0a add cl, BYTE PTR [rdx] 00b67 88 0c 10 mov BYTE PTR [rax+rdx], cl 00b6a 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 00b6e 49 83 e8 01 sub r8, 1 00b72 75 ec jne SHORT $LL300@stbi__crea 00b74 e9 3b 01 00 00 jmp $LN28@stbi__crea $LN124@stbi__crea: ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; 00b79 85 f6 test esi, esi 00b7b 0f 8e 33 01 00 00 jle $LN28@stbi__crea 00b81 4c 8b c8 mov r9, rax 00b84 4c 8b d3 mov r10, rbx 00b87 4d 2b ce sub r9, r14 00b8a 4d 2b d3 sub r10, r11 00b8d 4d 2b cb sub r9, r11 00b90 49 2b c3 sub rax, r11 00b93 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL20@stbi__crea: 00ba0 43 0f b6 14 0b movzx edx, BYTE PTR [r11+r9] 00ba5 41 0f b6 0b movzx ecx, BYTE PTR [r11] 00ba9 4d 8d 5b 01 lea r11, QWORD PTR [r11+1] 00bad 03 d1 add edx, ecx 00baf d1 ea shr edx, 1 00bb1 43 02 54 1a ff add dl, BYTE PTR [r10+r11-1] 00bb6 42 88 54 18 ff mov BYTE PTR [rax+r11-1], dl 00bbb 49 83 e8 01 sub r8, 1 00bbf 75 df jne SHORT $LL20@stbi__crea 00bc1 e9 ee 00 00 00 jmp $LN28@stbi__crea $LN125@stbi__crea: ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; 00bc6 85 f6 test esi, esi 00bc8 0f 8e e6 00 00 00 jle $LN28@stbi__crea 00bce 4c 8b d0 mov r10, rax 00bd1 4d 8b e3 mov r12, r11 00bd4 4d 2b d6 sub r10, r14 00bd7 4c 2b e0 sub r12, rax 00bda 49 8b ce mov rcx, r14 00bdd 48 2b c8 sub rcx, rax 00be0 4e 8d 2c 19 lea r13, QWORD PTR [rcx+r11] 00be4 4c 8d 3c 19 lea r15, QWORD PTR [rcx+rbx] 00be8 0f 1f 84 00 00 00 00 00 npad 8 $LL23@stbi__crea: 00bf0 45 0f b6 0a movzx r9d, BYTE PTR [r10] 00bf4 43 0f b6 34 22 movzx esi, BYTE PTR [r10+r12] ; 4141 : int p = a + b - c; 00bf9 41 8b c9 mov ecx, r9d ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; 00bfc 43 0f b6 2c 2a movzx ebp, BYTE PTR [r10+r13] ; 4141 : int p = a + b - c; 00c01 2b ce sub ecx, esi ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); 00c03 8b f9 mov edi, ecx 00c05 8d 14 29 lea edx, DWORD PTR [rcx+rbp] 00c08 8b c2 mov eax, edx 00c0a 41 2b c1 sub eax, r9d 00c0d 44 8b d8 mov r11d, eax 00c10 41 f7 db neg r11d 00c13 44 0f 48 d8 cmovs r11d, eax 00c17 f7 df neg edi 00c19 0f 48 f9 cmovs edi, ecx ; 4144 : int pc = abs(p - c); 00c1c 2b d6 sub edx, esi 00c1e 8b c2 mov eax, edx 00c20 f7 d8 neg eax 00c22 0f 48 c2 cmovs eax, edx ; 4145 : if (pa <= pb && pa <= pc) return a; 00c25 44 3b df cmp r11d, edi 00c28 7f 05 jg SHORT $LN215@stbi__crea 00c2a 44 3b d8 cmp r11d, eax 00c2d 7e 09 jle SHORT $LN216@stbi__crea $LN215@stbi__crea: ; 4146 : if (pb <= pc) return b; 00c2f 3b f8 cmp edi, eax 00c31 44 8b ce mov r9d, esi 00c34 44 0f 4e cd cmovle r9d, ebp $LN216@stbi__crea: ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; 00c38 47 02 0c 17 add r9b, BYTE PTR [r15+r10] 00c3c 47 88 0c 16 mov BYTE PTR [r14+r10], r9b 00c40 49 ff c2 inc r10 00c43 49 83 e8 01 sub r8, 1 00c47 75 a7 jne SHORT $LL23@stbi__crea 00c49 4c 8b ac 24 98 00 00 00 mov r13, QWORD PTR $T16[rsp] 00c51 8b 74 24 40 mov esi, DWORD PTR nk$1$[rsp] 00c55 eb 5d jmp SHORT $LN28@stbi__crea $LN126@stbi__crea: ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; 00c57 85 f6 test esi, esi 00c59 7e 59 jle SHORT $LN28@stbi__crea 00c5b 4c 8b c8 mov r9, rax 00c5e 48 8b d3 mov rdx, rbx 00c61 4d 2b ce sub r9, r14 00c64 4c 2b cb sub r9, rbx 00c67 48 2b c3 sub rax, rbx 00c6a 66 0f 1f 44 00 00 npad 6 $LL26@stbi__crea: 00c70 42 0f b6 0c 0a movzx ecx, BYTE PTR [rdx+r9] 00c75 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 00c79 d0 e9 shr cl, 1 00c7b 02 4a ff add cl, BYTE PTR [rdx-1] 00c7e 88 4c 10 ff mov BYTE PTR [rax+rdx-1], cl 00c82 49 83 e8 01 sub r8, 1 00c86 75 e8 jne SHORT $LL26@stbi__crea 00c88 eb 2a jmp SHORT $LN28@stbi__crea $LN127@stbi__crea: ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; 00c8a 85 f6 test esi, esi 00c8c 7e 26 jle SHORT $LN28@stbi__crea 00c8e 4c 8b c8 mov r9, rax 00c91 48 8b d3 mov rdx, rbx 00c94 4d 2b ce sub r9, r14 00c97 4c 2b cb sub r9, rbx 00c9a 48 2b c3 sub rax, rbx 00c9d 0f 1f 00 npad 3 $LL29@stbi__crea: ; 4145 : if (pa <= pb && pa <= pc) return a; 00ca0 42 0f b6 0c 0a movzx ecx, BYTE PTR [rdx+r9] ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; 00ca5 02 0a add cl, BYTE PTR [rdx] 00ca7 88 0c 10 mov BYTE PTR [rax+rdx], cl 00caa 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 00cae 49 83 e8 01 sub r8, 1 00cb2 75 ec jne SHORT $LL29@stbi__crea $LN28@stbi__crea: ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; 00cb4 48 63 c6 movsxd rax, esi 00cb7 48 03 d8 add rbx, rax $LN2@stbi__crea: ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { 00cba 8b 54 24 4c mov edx, DWORD PTR j$1$[rsp] 00cbe 45 33 c9 xor r9d, r9d 00cc1 8b b4 24 18 01 00 00 mov esi, DWORD PTR y$[rsp] 00cc8 ff c2 inc edx 00cca 44 8b bc 24 10 01 00 00 mov r15d, DWORD PTR x$[rsp] 00cd2 8b 4c 24 54 mov ecx, DWORD PTR img_width_bytes$1$[rsp] 00cd6 44 8b 9c 24 f0 00 00 00 mov r11d, DWORD PTR img_n$1$[rsp] 00cde 89 54 24 4c mov DWORD PTR j$1$[rsp], edx 00ce2 3b d6 cmp edx, esi 00ce4 73 5c jae SHORT $LN485@stbi__crea 00ce6 44 8b 64 24 50 mov r12d, DWORD PTR filter_bytes$1$[rsp] 00ceb 4c 8b 44 24 28 mov r8, QWORD PTR $T13[rsp] 00cf0 48 8b 7c 24 30 mov rdi, QWORD PTR $T14[rsp] 00cf5 e9 26 f5 ff ff jmp $LL4@stbi__crea $LN261@stbi__crea: ; 431 : stbi__g_failure_reason = str; 00cfa 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d00 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d09 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00d0e 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d12 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@MKGNGALN@invalid?5width@ ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); 00d19 e9 89 f4 ff ff jmp $LN651@stbi__crea $LN260@stbi__crea: ; 431 : stbi__g_failure_reason = str; 00d1e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d24 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d2d b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00d32 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d36 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@FBBCPGMN@invalid?5filter@ ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); 00d3d e9 65 f4 ff ff jmp $LN651@stbi__crea $LN485@stbi__crea: ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { 00d42 44 8b 6c 24 20 mov r13d, DWORD PTR a$1$[rsp] 00d47 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:__ImageBase 00d4e 4c 8b 94 24 a0 00 00 00 mov r10, QWORD PTR cur$1$[rsp] $LN3@stbi__crea: ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { 00d56 48 63 9c 24 20 01 00 00 movsxd rbx, DWORD PTR depth$[rsp] 00d5e 83 fb 08 cmp ebx, 8 00d61 0f 8d 6e 04 00 00 jge $LN136@stbi__crea ; 4284 : for (j = 0; j < y; ++j) { 00d67 85 f6 test esi, esi 00d69 0f 84 a6 04 00 00 je $LN96@stbi__crea ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range 00d6f 44 8b b4 24 08 01 00 00 mov r14d, DWORD PTR out_n$[rsp] 00d77 48 8d b3 00 00 00 00 lea rsi, QWORD PTR stbi__depth_scale_table[rbx] 00d7e 44 8b a4 24 28 01 00 00 mov r12d, DWORD PTR color$[rsp] 00d86 49 03 f0 add rsi, r8 00d89 45 0f af f7 imul r14d, r15d 00d8d 49 63 ef movsxd rbp, r15d 00d90 44 8b f9 mov r15d, ecx 00d93 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL79@stbi__crea: ; 4285 : stbi_uc* cur = a->out + stride * j; 00da0 48 8b 44 24 30 mov rax, QWORD PTR $T14[rsp] 00da5 41 8b f9 mov edi, r9d 00da8 0f af 7c 24 38 imul edi, DWORD PTR stride$1$[rsp] ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; 00dad 4d 8b ce mov r9, r14 00db0 4d 2b cf sub r9, r15 00db3 4c 03 cf add r9, rdi 00db6 4c 03 c8 add r9, rax 00db9 4c 8d 04 07 lea r8, QWORD PTR [rdi+rax] ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range 00dbd 45 85 e4 test r12d, r12d 00dc0 75 06 jne SHORT $LN159@stbi__crea 00dc2 44 0f b6 16 movzx r10d, BYTE PTR [rsi] 00dc6 eb 03 jmp SHORT $LN160@stbi__crea $LN159@stbi__crea: 00dc8 41 b2 01 mov r10b, 1 $LN160@stbi__crea: ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { 00dcb 41 8b cd mov ecx, r13d 00dce 83 fb 04 cmp ebx, 4 00dd1 0f 85 8c 00 00 00 jne $LN138@stbi__crea ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { 00dd7 89 4c 24 20 mov DWORD PTR a$1$[rsp], ecx 00ddb 8b d9 mov ebx, ecx 00ddd 83 f9 02 cmp ecx, 2 00de0 7c 53 jl SHORT $LN81@stbi__crea 00de2 44 8b d9 mov r11d, ecx 00de5 89 4c 24 20 mov DWORD PTR a$1$[rsp], ecx 00de9 49 d1 eb shr r11, 1 00dec 41 8b c3 mov eax, r11d 00def f7 d8 neg eax 00df1 8d 1c 41 lea ebx, DWORD PTR [rcx+rax*2] 00df4 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL82@stbi__crea: ; 4299 : *cur++ = scale * ((*in >> 4)); 00e00 41 0f b6 01 movzx eax, BYTE PTR [r9] 00e04 c0 e8 04 shr al, 4 00e07 0f b6 d0 movzx edx, al 00e0a 41 0f b6 ca movzx ecx, r10b 00e0e 0f af d1 imul edx, ecx ; 4300 : *cur++ = scale * ((*in) & 0x0f); 00e11 41 0f b6 ca movzx ecx, r10b 00e15 41 88 10 mov BYTE PTR [r8], dl 00e18 41 0f b6 01 movzx eax, BYTE PTR [r9] 00e1c 49 ff c1 inc r9 00e1f 24 0f and al, 15 00e21 0f b6 d0 movzx edx, al 00e24 0f af d1 imul edx, ecx 00e27 41 88 50 01 mov BYTE PTR [r8+1], dl 00e2b 49 83 c0 02 add r8, 2 00e2f 49 83 eb 01 sub r11, 1 00e33 75 cb jne SHORT $LL82@stbi__crea $LN81@stbi__crea: ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); 00e35 44 8b 6c 24 20 mov r13d, DWORD PTR a$1$[rsp] 00e3a 44 8b 9c 24 f0 00 00 00 mov r11d, DWORD PTR img_n$1$[rsp] 00e42 85 db test ebx, ebx 00e44 0f 8e de 02 00 00 jle $LN650@stbi__crea 00e4a 41 0f b6 01 movzx eax, BYTE PTR [r9] 00e4e c0 e8 04 shr al, 4 00e51 0f b6 d0 movzx edx, al 00e54 41 0f b6 ca movzx ecx, r10b 00e58 0f af d1 imul edx, ecx 00e5b 41 88 10 mov BYTE PTR [r8], dl ; 4303 : } 00e5e e9 c5 02 00 00 jmp $LN650@stbi__crea $LN138@stbi__crea: ; 4304 : else if (depth == 2) { 00e63 83 fb 02 cmp ebx, 2 00e66 0f 85 e8 00 00 00 jne $LN141@stbi__crea ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { 00e6c 89 4c 24 20 mov DWORD PTR a$1$[rsp], ecx 00e70 48 8b d9 mov rbx, rcx 00e73 83 f9 04 cmp ecx, 4 00e76 7c 7d jl SHORT $LN84@stbi__crea 00e78 4c 8b d9 mov r11, rcx 00e7b 89 4c 24 20 mov DWORD PTR a$1$[rsp], ecx 00e7f 49 c1 eb 02 shr r11, 2 00e83 41 8b c3 mov eax, r11d 00e86 f7 d8 neg eax 00e88 8d 1c 81 lea ebx, DWORD PTR [rcx+rax*4] 00e8b 0f 1f 44 00 00 npad 5 $LL85@stbi__crea: ; 4306 : *cur++ = scale * ((*in >> 6)); 00e90 41 0f b6 01 movzx eax, BYTE PTR [r9] 00e94 c0 e8 06 shr al, 6 00e97 0f b6 d0 movzx edx, al 00e9a 41 0f b6 ca movzx ecx, r10b 00e9e 0f af d1 imul edx, ecx ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); 00ea1 41 0f b6 c2 movzx eax, r10b 00ea5 41 88 10 mov BYTE PTR [r8], dl 00ea8 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00eac c0 e9 04 shr cl, 4 00eaf 80 e1 03 and cl, 3 00eb2 0f b6 c9 movzx ecx, cl 00eb5 0f af c8 imul ecx, eax ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); 00eb8 41 0f b6 c2 movzx eax, r10b 00ebc 41 88 48 01 mov BYTE PTR [r8+1], cl 00ec0 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00ec4 c0 e9 02 shr cl, 2 00ec7 80 e1 03 and cl, 3 00eca 0f b6 c9 movzx ecx, cl 00ecd 0f af c8 imul ecx, eax 00ed0 41 88 48 02 mov BYTE PTR [r8+2], cl ; 4309 : *cur++ = scale * ((*in) & 0x03); 00ed4 41 0f b6 01 movzx eax, BYTE PTR [r9] 00ed8 49 ff c1 inc r9 00edb 24 03 and al, 3 00edd 41 0f b6 ca movzx ecx, r10b 00ee1 0f b6 d0 movzx edx, al 00ee4 0f af d1 imul edx, ecx 00ee7 41 88 50 03 mov BYTE PTR [r8+3], dl 00eeb 49 83 c0 04 add r8, 4 00eef 49 83 eb 01 sub r11, 1 00ef3 75 9b jne SHORT $LL85@stbi__crea $LN84@stbi__crea: ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); 00ef5 85 db test ebx, ebx 00ef7 7e 17 jle SHORT $LN143@stbi__crea 00ef9 41 0f b6 01 movzx eax, BYTE PTR [r9] 00efd c0 e8 06 shr al, 6 00f00 0f b6 d0 movzx edx, al 00f03 41 0f b6 ca movzx ecx, r10b 00f07 0f af d1 imul edx, ecx 00f0a 41 88 10 mov BYTE PTR [r8], dl 00f0d 49 ff c0 inc r8 $LN143@stbi__crea: ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); 00f10 83 fb 01 cmp ebx, 1 00f13 7e 1a jle SHORT $LN144@stbi__crea 00f15 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00f19 c0 e9 04 shr cl, 4 00f1c 80 e1 03 and cl, 3 00f1f 41 0f b6 c2 movzx eax, r10b 00f23 0f b6 c9 movzx ecx, cl 00f26 0f af c8 imul ecx, eax 00f29 41 88 08 mov BYTE PTR [r8], cl 00f2c 49 ff c0 inc r8 $LN144@stbi__crea: ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); 00f2f 44 8b 6c 24 20 mov r13d, DWORD PTR a$1$[rsp] 00f34 44 8b 9c 24 f0 00 00 00 mov r11d, DWORD PTR img_n$1$[rsp] 00f3c 83 fb 02 cmp ebx, 2 00f3f 0f 8e e3 01 00 00 jle $LN650@stbi__crea 00f45 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00f49 c0 e9 02 shr cl, 2 00f4c 80 e1 03 and cl, 3 ; 4314 : } 00f4f e9 c7 01 00 00 jmp $LN652@stbi__crea $LN141@stbi__crea: ; 4315 : else if (depth == 1) { 00f54 44 8b e9 mov r13d, ecx 00f57 83 fb 01 cmp ebx, 1 00f5a 0f 85 cd 01 00 00 jne $LN153@stbi__crea ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { 00f60 4c 8b d9 mov r11, rcx 00f63 83 f9 08 cmp ecx, 8 00f66 0f 8c dc 00 00 00 jl $LN87@stbi__crea 00f6c 48 8b d9 mov rbx, rcx 00f6f 48 c1 eb 03 shr rbx, 3 00f73 8b c3 mov eax, ebx 00f75 f7 d8 neg eax 00f77 44 8d 1c c1 lea r11d, DWORD PTR [rcx+rax*8] 00f7b 0f 1f 44 00 00 npad 5 $LL88@stbi__crea: ; 4317 : *cur++ = scale * ((*in >> 7)); 00f80 41 0f b6 01 movzx eax, BYTE PTR [r9] 00f84 c0 e8 07 shr al, 7 00f87 0f b6 d0 movzx edx, al 00f8a 41 0f b6 ca movzx ecx, r10b 00f8e 0f af d1 imul edx, ecx ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); 00f91 41 0f b6 c2 movzx eax, r10b 00f95 41 88 10 mov BYTE PTR [r8], dl 00f98 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00f9c c0 e9 06 shr cl, 6 00f9f 80 e1 01 and cl, 1 00fa2 0f b6 c9 movzx ecx, cl 00fa5 0f af c8 imul ecx, eax ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); 00fa8 41 0f b6 c2 movzx eax, r10b 00fac 41 88 48 01 mov BYTE PTR [r8+1], cl 00fb0 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00fb4 c0 e9 05 shr cl, 5 00fb7 80 e1 01 and cl, 1 00fba 0f b6 c9 movzx ecx, cl 00fbd 0f af c8 imul ecx, eax ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); 00fc0 41 0f b6 c2 movzx eax, r10b 00fc4 41 88 48 02 mov BYTE PTR [r8+2], cl 00fc8 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00fcc c0 e9 04 shr cl, 4 00fcf 80 e1 01 and cl, 1 00fd2 0f b6 c9 movzx ecx, cl 00fd5 0f af c8 imul ecx, eax ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); 00fd8 41 0f b6 c2 movzx eax, r10b 00fdc 41 88 48 03 mov BYTE PTR [r8+3], cl 00fe0 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00fe4 c0 e9 03 shr cl, 3 00fe7 80 e1 01 and cl, 1 00fea 0f b6 c9 movzx ecx, cl 00fed 0f af c8 imul ecx, eax ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); 00ff0 41 0f b6 c2 movzx eax, r10b 00ff4 41 88 48 04 mov BYTE PTR [r8+4], cl 00ff8 41 0f b6 09 movzx ecx, BYTE PTR [r9] 00ffc c0 e9 02 shr cl, 2 00fff 80 e1 01 and cl, 1 01002 0f b6 c9 movzx ecx, cl 01005 0f af c8 imul ecx, eax ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); 01008 41 0f b6 c2 movzx eax, r10b 0100c 41 88 48 05 mov BYTE PTR [r8+5], cl 01010 41 0f b6 09 movzx ecx, BYTE PTR [r9] 01014 d0 e9 shr cl, 1 01016 80 e1 01 and cl, 1 01019 0f b6 c9 movzx ecx, cl 0101c 0f af c8 imul ecx, eax 0101f 41 88 48 06 mov BYTE PTR [r8+6], cl ; 4324 : *cur++ = scale * ((*in) & 0x01); 01023 41 0f b6 01 movzx eax, BYTE PTR [r9] 01027 49 ff c1 inc r9 0102a 24 01 and al, 1 0102c 41 0f b6 ca movzx ecx, r10b 01030 0f b6 d0 movzx edx, al 01033 0f af d1 imul edx, ecx 01036 41 88 50 07 mov BYTE PTR [r8+7], dl 0103a 49 83 c0 08 add r8, 8 0103e 48 83 eb 01 sub rbx, 1 01042 0f 85 38 ff ff ff jne $LL88@stbi__crea $LN87@stbi__crea: ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); 01048 45 85 db test r11d, r11d 0104b 7e 17 jle SHORT $LN147@stbi__crea 0104d 41 0f b6 01 movzx eax, BYTE PTR [r9] 01051 c0 e8 07 shr al, 7 01054 0f b6 d0 movzx edx, al 01057 41 0f b6 ca movzx ecx, r10b 0105b 0f af d1 imul edx, ecx 0105e 41 88 10 mov BYTE PTR [r8], dl 01061 49 ff c0 inc r8 $LN147@stbi__crea: ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); 01064 41 83 fb 01 cmp r11d, 1 01068 7e 1a jle SHORT $LN148@stbi__crea 0106a 41 0f b6 09 movzx ecx, BYTE PTR [r9] 0106e c0 e9 06 shr cl, 6 01071 80 e1 01 and cl, 1 01074 41 0f b6 c2 movzx eax, r10b 01078 0f b6 c9 movzx ecx, cl 0107b 0f af c8 imul ecx, eax 0107e 41 88 08 mov BYTE PTR [r8], cl 01081 49 ff c0 inc r8 $LN148@stbi__crea: ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); 01084 41 83 fb 02 cmp r11d, 2 01088 7e 1a jle SHORT $LN149@stbi__crea 0108a 41 0f b6 09 movzx ecx, BYTE PTR [r9] 0108e c0 e9 05 shr cl, 5 01091 80 e1 01 and cl, 1 01094 41 0f b6 c2 movzx eax, r10b 01098 0f b6 c9 movzx ecx, cl 0109b 0f af c8 imul ecx, eax 0109e 41 88 08 mov BYTE PTR [r8], cl 010a1 49 ff c0 inc r8 $LN149@stbi__crea: ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); 010a4 41 83 fb 03 cmp r11d, 3 010a8 7e 1a jle SHORT $LN150@stbi__crea 010aa 41 0f b6 09 movzx ecx, BYTE PTR [r9] 010ae c0 e9 04 shr cl, 4 010b1 80 e1 01 and cl, 1 010b4 41 0f b6 c2 movzx eax, r10b 010b8 0f b6 c9 movzx ecx, cl 010bb 0f af c8 imul ecx, eax 010be 41 88 08 mov BYTE PTR [r8], cl 010c1 49 ff c0 inc r8 $LN150@stbi__crea: ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); 010c4 41 83 fb 04 cmp r11d, 4 010c8 7e 1a jle SHORT $LN151@stbi__crea 010ca 41 0f b6 09 movzx ecx, BYTE PTR [r9] 010ce c0 e9 03 shr cl, 3 010d1 80 e1 01 and cl, 1 010d4 41 0f b6 c2 movzx eax, r10b 010d8 0f b6 c9 movzx ecx, cl 010db 0f af c8 imul ecx, eax 010de 41 88 08 mov BYTE PTR [r8], cl 010e1 49 ff c0 inc r8 $LN151@stbi__crea: ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); 010e4 41 83 fb 05 cmp r11d, 5 010e8 7e 1a jle SHORT $LN152@stbi__crea 010ea 41 0f b6 09 movzx ecx, BYTE PTR [r9] 010ee c0 e9 02 shr cl, 2 010f1 80 e1 01 and cl, 1 010f4 41 0f b6 c2 movzx eax, r10b 010f8 0f b6 c9 movzx ecx, cl 010fb 0f af c8 imul ecx, eax 010fe 41 88 08 mov BYTE PTR [r8], cl 01101 49 ff c0 inc r8 $LN152@stbi__crea: ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); 01104 41 83 fb 06 cmp r11d, 6 01108 44 8b 9c 24 f0 00 00 00 mov r11d, DWORD PTR img_n$1$[rsp] 01110 7e 16 jle SHORT $LN650@stbi__crea 01112 41 0f b6 09 movzx ecx, BYTE PTR [r9] 01116 d0 e9 shr cl, 1 01118 80 e1 01 and cl, 1 $LN652@stbi__crea: ; 4333 : } ; 4334 : if (img_n != out_n) { 0111b 41 0f b6 c2 movzx eax, r10b 0111f 0f b6 c9 movzx ecx, cl 01122 0f af c8 imul ecx, eax 01125 41 88 08 mov BYTE PTR [r8], cl $LN650@stbi__crea: 01128 48 8b 44 24 30 mov rax, QWORD PTR $T14[rsp] $LN153@stbi__crea: 0112d 44 3b 9c 24 08 01 00 00 cmp r11d, DWORD PTR out_n$[rsp] 01135 74 72 je SHORT $LN77@stbi__crea ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; 01137 48 8d 14 07 lea rdx, QWORD PTR [rdi+rax] 0113b 48 8d 4d ff lea rcx, QWORD PTR [rbp-1] ; 4338 : if (img_n == 1) { 0113f 41 83 fb 01 cmp r11d, 1 01143 75 1f jne SHORT $LN155@stbi__crea ; 4339 : for (q = x - 1; q >= 0; --q) { 01145 48 85 c9 test rcx, rcx 01148 78 5f js SHORT $LN77@stbi__crea 0114a 66 0f 1f 44 00 00 npad 6 $LL91@stbi__crea: ; 4340 : cur[q * 2 + 1] = 255; 01150 c6 44 4a 01 ff mov BYTE PTR [rdx+rcx*2+1], 255 ; 000000ffH ; 4341 : cur[q * 2 + 0] = cur[q]; 01155 0f b6 04 11 movzx eax, BYTE PTR [rcx+rdx] 01159 88 04 4a mov BYTE PTR [rdx+rcx*2], al 0115c 48 83 e9 01 sub rcx, 1 01160 79 ee jns SHORT $LL91@stbi__crea ; 4342 : } ; 4343 : } 01162 eb 45 jmp SHORT $LN77@stbi__crea $LN155@stbi__crea: ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { 01164 48 85 c9 test rcx, rcx 01167 78 40 js SHORT $LN77@stbi__crea 01169 4c 8d 04 4d 01 00 00 00 lea r8, QWORD PTR [rcx*2+1] 01171 4c 03 c2 add r8, rdx 01174 48 8d 14 8a lea rdx, QWORD PTR [rdx+rcx*4] 01178 4c 03 c1 add r8, rcx 0117b 48 83 c2 02 add rdx, 2 0117f 90 npad 1 $LL94@stbi__crea: 01180 48 83 e9 01 sub rcx, 1 ; 4347 : cur[q * 4 + 3] = 255; 01184 c6 42 01 ff mov BYTE PTR [rdx+1], 255 ; 000000ffH ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; 01188 41 0f b6 40 01 movzx eax, BYTE PTR [r8+1] 0118d 4d 8d 40 fd lea r8, QWORD PTR [r8-3] 01191 88 02 mov BYTE PTR [rdx], al 01193 48 8d 52 fc lea rdx, QWORD PTR [rdx-4] ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; 01197 41 0f b6 40 03 movzx eax, BYTE PTR [r8+3] 0119c 88 42 03 mov BYTE PTR [rdx+3], al ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; 0119f 41 0f b6 40 02 movzx eax, BYTE PTR [r8+2] 011a4 88 42 02 mov BYTE PTR [rdx+2], al 011a7 79 d7 jns SHORT $LL94@stbi__crea $LN77@stbi__crea: ; 4284 : for (j = 0; j < y; ++j) { 011a9 4c 8b 4c 24 78 mov r9, QWORD PTR tv5875[rsp] 011ae 8b 9c 24 20 01 00 00 mov ebx, DWORD PTR depth$[rsp] 011b5 41 ff c1 inc r9d 011b8 4c 89 4c 24 78 mov QWORD PTR tv5875[rsp], r9 011bd 44 3b 8c 24 18 01 00 00 cmp r9d, DWORD PTR y$[rsp] 011c5 0f 82 d5 fb ff ff jb $LL79@stbi__crea ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; 011cb b8 01 00 00 00 mov eax, 1 011d0 e9 d8 ef ff ff jmp $LN649@stbi__crea $LN136@stbi__crea: ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { 011d5 83 fb 10 cmp ebx, 16 011d8 75 3b jne SHORT $LN96@stbi__crea ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { 011da 8b 84 24 08 01 00 00 mov eax, DWORD PTR out_n$[rsp] 011e1 4d 8b c2 mov r8, r10 011e4 41 0f af c7 imul eax, r15d 011e8 0f af c6 imul eax, esi 011eb 85 c0 test eax, eax 011ed 74 26 je SHORT $LN96@stbi__crea ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; 011ef 44 8b c8 mov r9d, eax $LL97@stbi__crea: ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; 011f2 41 0f b6 12 movzx edx, BYTE PTR [r10] 011f6 4d 8d 52 02 lea r10, QWORD PTR [r10+2] 011fa 41 0f b6 48 01 movzx ecx, BYTE PTR [r8+1] 011ff 4d 8d 40 02 lea r8, QWORD PTR [r8+2] 01203 66 c1 e2 08 shl dx, 8 01207 66 0b d1 or dx, cx 0120a 66 41 89 50 fe mov WORD PTR [r8-2], dx 0120f 49 83 e9 01 sub r9, 1 01213 75 dd jne SHORT $LL97@stbi__crea $LN96@stbi__crea: ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; 01215 b8 01 00 00 00 mov eax, 1 0121a e9 8e ef ff ff jmp $LN649@stbi__crea $LN384@stbi__crea: ; 431 : stbi__g_failure_reason = str; 0121f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 01225 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0122e b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 01233 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 01237 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); 0123e e9 64 ef ff ff jmp $LN651@stbi__crea $LN388@stbi__crea: ; 508 : if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; 01243 4c 89 46 18 mov QWORD PTR [rsi+24], r8 $LN387@stbi__crea: ; 431 : stbi__g_failure_reason = str; 01247 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0124d 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 01256 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0125b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0125f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 01266 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); 0126a 33 c0 xor eax, eax 0126c e9 44 ef ff ff jmp $LN1@stbi__crea 01271 0f 1f 00 npad 3 $LN398@stbi__crea: ; 4370 : } 01274 00 00 00 00 DD $LL406@stbi__crea 01278 00 00 00 00 DD $LL407@stbi__crea 0127c 00 00 00 00 DD $LL447@stbi__crea 01280 00 00 00 00 DD $LL448@stbi__crea 01284 00 00 00 00 DD $LL449@stbi__crea 01288 00 00 00 00 DD $LL450@stbi__crea 0128c 00 00 00 00 DD $LL451@stbi__crea $LN397@stbi__crea: 01290 00 00 00 00 DD $LN128@stbi__crea 01294 00 00 00 00 DD $LN129@stbi__crea 01298 00 00 00 00 DD $LN130@stbi__crea 0129c 00 00 00 00 DD $LN131@stbi__crea 012a0 00 00 00 00 DD $LN132@stbi__crea 012a4 00 00 00 00 DD $LN133@stbi__crea 012a8 00 00 00 00 DD $LN134@stbi__crea $LN394@stbi__crea: 012ac 00 00 00 00 DD $LN121@stbi__crea 012b0 00 00 00 00 DD $LN122@stbi__crea 012b4 00 00 00 00 DD $LN123@stbi__crea 012b8 00 00 00 00 DD $LN124@stbi__crea 012bc 00 00 00 00 DD $LN125@stbi__crea 012c0 00 00 00 00 DD $LN126@stbi__crea 012c4 00 00 00 00 DD $LN127@stbi__crea stbi__create_png_image_raw ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__create_png_image _TEXT SEGMENT tv892 = 64 p$1$ = 68 tv900 = 72 tv906 = 76 tv905 = 80 x$1$ = 84 y$1$ = 88 tv890 = 92 tv901 = 96 img_len$1$ = 100 final$1$ = 104 tv889 = 112 tv902 = 120 xspc$4 = 128 xorig$5 = 160 yspc$6 = 192 yorig$7 = 224 a$ = 336 image_data$ = 344 image_data_len$ = 352 out_n$ = 360 depth$ = 368 color$ = 376 j$1$ = 384 interlaced$ = 384 stbi__create_png_image PROC ; COMDAT ; 4373 : { 00000 44 89 4c 24 20 mov DWORD PTR [rsp+32], r9d 00005 44 89 44 24 18 mov DWORD PTR [rsp+24], r8d 0000a 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx 0000f 48 89 4c 24 08 mov QWORD PTR [rsp+8], rcx 00014 53 push rbx 00015 55 push rbp 00016 57 push rdi 00017 41 54 push r12 00019 41 56 push r14 0001b 48 81 ec 20 01 00 00 sub rsp, 288 ; 00000120H ; 4374 : int bytes = (depth == 16 ? 2 : 1); 00022 33 db xor ebx, ebx 00024 48 8b fa mov rdi, rdx 00027 8b 94 24 70 01 00 00 mov edx, DWORD PTR depth$[rsp] 0002e 8b eb mov ebp, ebx 00030 83 fa 10 cmp edx, 16 00033 4c 8b e1 mov r12, rcx ; 4375 : int out_bytes = out_n * bytes; 00036 48 8b 09 mov rcx, QWORD PTR [rcx] 00039 45 8b f0 mov r14d, r8d 0003c 40 0f 94 c5 sete bpl 00040 ff c5 inc ebp 00042 41 0f af e9 imul ebp, r9d ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) 00046 39 9c 24 80 01 00 00 cmp DWORD PTR interlaced$[rsp], ebx 0004d 75 36 jne SHORT $LN11@stbi__crea ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); 0004f 8b 84 24 78 01 00 00 mov eax, DWORD PTR color$[rsp] 00056 89 44 24 38 mov DWORD PTR [rsp+56], eax 0005a 8b 41 04 mov eax, DWORD PTR [rcx+4] 0005d 89 54 24 30 mov DWORD PTR [rsp+48], edx 00061 48 8b d7 mov rdx, rdi 00064 89 44 24 28 mov DWORD PTR [rsp+40], eax 00068 8b 01 mov eax, DWORD PTR [rcx] 0006a 49 8b cc mov rcx, r12 0006d 89 44 24 20 mov DWORD PTR [rsp+32], eax 00071 e8 00 00 00 00 call stbi__create_png_image_raw ; 4415 : } 00076 48 81 c4 20 01 00 00 add rsp, 288 ; 00000120H 0007d 41 5e pop r14 0007f 41 5c pop r12 00081 5f pop rdi 00082 5d pop rbp 00083 5b pop rbx 00084 c3 ret 0 $LN11@stbi__crea: ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); 00085 44 8b 41 04 mov r8d, DWORD PTR [rcx+4] 00089 8b 09 mov ecx, DWORD PTR [rcx] 0008b 48 89 b4 24 18 01 00 00 mov QWORD PTR [rsp+280], rsi ; 467 : if (a < 0 || b < 0) return 0; 00093 85 c9 test ecx, ecx 00095 0f 88 76 03 00 00 js $LN53@stbi__crea 0009b 45 85 c0 test r8d, r8d 0009e 0f 88 6d 03 00 00 js $LN53@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000a4 74 11 je SHORT $LN57@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000a6 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 000ab 99 cdq 000ac 41 f7 f8 idiv r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 000af 3b c8 cmp ecx, eax 000b1 0f 8f 5a 03 00 00 jg $LN53@stbi__crea $LN57@stbi__crea: 000b7 41 0f af c8 imul ecx, r8d ; 467 : if (a < 0 || b < 0) return 0; 000bb 85 c9 test ecx, ecx 000bd 0f 88 4e 03 00 00 js $LN53@stbi__crea 000c3 85 ed test ebp, ebp 000c5 0f 88 46 03 00 00 js $LN53@stbi__crea ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000cb 74 10 je SHORT $LN17@stbi__crea ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000cd b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 000d2 99 cdq 000d3 f7 fd idiv ebp ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 000d5 3b c8 cmp ecx, eax 000d7 0f 8f 34 03 00 00 jg $LN53@stbi__crea $LN17@stbi__crea: ; 509 : return stbi__malloc(a * b * c + add); 000dd 0f af cd imul ecx, ebp 000e0 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 000e3 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 000e9 48 89 44 24 68 mov QWORD PTR final$1$[rsp], rax ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); 000ee 48 85 c0 test rax, rax 000f1 0f 84 1a 03 00 00 je $LN53@stbi__crea 000f7 4c 89 ac 24 10 01 00 00 mov QWORD PTR [rsp+272], r13 ; 4384 : for (p = 0; p < 7; ++p) { 000ff 44 8b cb mov r9d, ebx 00102 4c 89 bc 24 08 01 00 00 mov QWORD PTR [rsp+264], r15 0010a 4c 8b eb mov r13, rbx 0010d 89 5c 24 44 mov DWORD PTR p$1$[rsp], ebx 00111 48 89 5c 24 70 mov QWORD PTR tv889[rsp], rbx 00116 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL4@stbi__crea: ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; 00120 66 0f 6f 05 00 00 00 00 movdqa xmm0, XMMWORD PTR __xmm@00000002000000000000000400000000 ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; 00128 33 d2 xor edx, edx 0012a 4d 8b 04 24 mov r8, QWORD PTR [r12] 0012e f3 0f 7f 84 24 a0 00 00 00 movdqu XMMWORD PTR xorig$5[rsp], xmm0 00137 c7 84 24 90 00 00 00 02 00 00 00 mov DWORD PTR xspc$4[rsp+16], 2 00142 66 0f 6f 05 00 00 00 00 movdqa xmm0, XMMWORD PTR __xmm@00000000000000040000000000000000 0014a f3 0f 7f 84 24 e0 00 00 00 movdqu XMMWORD PTR yorig$7[rsp], xmm0 00153 c7 84 24 94 00 00 00 02 00 00 00 mov DWORD PTR xspc$4[rsp+20], 2 0015e 66 0f 6f 05 00 00 00 00 movdqa xmm0, XMMWORD PTR __xmm@00000004000000040000000800000008 00166 f3 0f 7f 84 24 80 00 00 00 movdqu XMMWORD PTR xspc$4[rsp], xmm0 0016f c7 84 24 98 00 00 00 01 00 00 00 mov DWORD PTR xspc$4[rsp+24], 1 0017a 46 8b 94 2c 80 00 00 00 mov r10d, DWORD PTR xspc$4[rsp+r13] 00182 41 8b ca mov ecx, r10d 00185 66 0f 6f 05 00 00 00 00 movdqa xmm0, XMMWORD PTR __xmm@00000004000000080000000800000008 0018d 89 9c 24 b0 00 00 00 mov DWORD PTR xorig$5[rsp+16], ebx 00194 48 c7 84 24 b4 00 00 00 01 00 00 00 mov QWORD PTR xorig$5[rsp+20], 1 001a0 42 8b 84 2c a0 00 00 00 mov eax, DWORD PTR xorig$5[rsp+r13] 001a8 2b c8 sub ecx, eax 001aa 89 44 24 50 mov DWORD PTR tv905[rsp], eax 001ae 41 8b 00 mov eax, DWORD PTR [r8] 001b1 ff c8 dec eax 001b3 48 c7 84 24 f0 00 00 00 02 00 00 00 mov QWORD PTR yorig$7[rsp+16], 2 001bf 03 c1 add eax, ecx 001c1 c7 84 24 f8 00 00 00 01 00 00 00 mov DWORD PTR yorig$7[rsp+24], 1 001cc 41 f7 f2 div r10d 001cf f3 0f 7f 84 24 c0 00 00 00 movdqu XMMWORD PTR yspc$6[rsp], xmm0 001d8 44 8b f8 mov r15d, eax ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; 001db 42 8b 84 2c e0 00 00 00 mov eax, DWORD PTR yorig$7[rsp+r13] 001e3 c7 84 24 d0 00 00 00 04 00 00 00 mov DWORD PTR yspc$6[rsp+16], 4 001ee c7 84 24 d4 00 00 00 02 00 00 00 mov DWORD PTR yspc$6[rsp+20], 2 001f9 c7 84 24 d8 00 00 00 02 00 00 00 mov DWORD PTR yspc$6[rsp+24], 2 00204 42 8b b4 2c c0 00 00 00 mov esi, DWORD PTR yspc$6[rsp+r13] 0020c 44 89 54 24 4c mov DWORD PTR tv906[rsp], r10d 00211 44 89 7c 24 54 mov DWORD PTR x$1$[rsp], r15d 00216 89 74 24 60 mov DWORD PTR tv901[rsp], esi 0021a 89 44 24 48 mov DWORD PTR tv900[rsp], eax ; 4393 : if (x && y) { 0021e 45 85 ff test r15d, r15d 00221 0f 84 8a 01 00 00 je $LN2@stbi__crea ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; 00227 41 8b 48 04 mov ecx, DWORD PTR [r8+4] 0022b 33 d2 xor edx, edx 0022d 2b c8 sub ecx, eax 0022f 8d 41 ff lea eax, DWORD PTR [rcx-1] 00232 03 c6 add eax, esi 00234 f7 f6 div esi 00236 89 44 24 58 mov DWORD PTR y$1$[rsp], eax 0023a 8b f8 mov edi, eax ; 4393 : if (x && y) { 0023c 85 c0 test eax, eax 0023e 0f 84 6d 01 00 00 je $LN2@stbi__crea ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; 00244 8b 84 24 70 01 00 00 mov eax, DWORD PTR depth$[rsp] 0024b 41 8b df mov ebx, r15d 0024e 41 0f af 58 08 imul ebx, DWORD PTR [r8+8] ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { 00253 45 8b c6 mov r8d, r14d 00256 8b 8c 24 78 01 00 00 mov ecx, DWORD PTR color$[rsp] 0025d 44 8b 8c 24 68 01 00 00 mov r9d, DWORD PTR out_n$[rsp] 00265 48 8b 94 24 58 01 00 00 mov rdx, QWORD PTR image_data$[rsp] 0026d 89 4c 24 38 mov DWORD PTR [rsp+56], ecx 00271 49 8b cc mov rcx, r12 00274 0f af d8 imul ebx, eax 00277 89 44 24 30 mov DWORD PTR [rsp+48], eax 0027b 89 7c 24 28 mov DWORD PTR [rsp+40], edi 0027f 44 89 7c 24 20 mov DWORD PTR [rsp+32], r15d 00284 83 c3 07 add ebx, 7 00287 c1 fb 03 sar ebx, 3 0028a ff c3 inc ebx 0028c 0f af df imul ebx, edi 0028f 89 5c 24 64 mov DWORD PTR img_len$1$[rsp], ebx 00293 e8 00 00 00 00 call stbi__create_png_image_raw 00298 85 c0 test eax, eax 0029a 0f 84 62 01 00 00 je $LN43@stbi__crea ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { 002a0 45 33 f6 xor r14d, r14d 002a3 44 89 b4 24 80 01 00 00 mov DWORD PTR j$1$[rsp], r14d 002ab 85 ff test edi, edi 002ad 0f 8e cf 00 00 00 jle $LN6@stbi__crea 002b3 45 33 ed xor r13d, r13d 002b6 41 8b c7 mov eax, r15d 002b9 0f af c5 imul eax, ebp 002bc 44 89 6c 24 40 mov DWORD PTR tv892[rsp], r13d 002c1 89 44 24 5c mov DWORD PTR tv890[rsp], eax $LL7@stbi__crea: ; 4400 : for (i = 0; i < x; ++i) { 002c5 45 85 ff test r15d, r15d 002c8 0f 8e 87 00 00 00 jle $LN5@stbi__crea ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, 002ce 4c 8b 84 24 50 01 00 00 mov r8, QWORD PTR a$[rsp] 002d6 8b fe mov edi, esi 002d8 44 8b 64 24 4c mov r12d, DWORD PTR tv906[rsp] 002dd 41 8b f5 mov esi, r13d 002e0 8b 5c 24 50 mov ebx, DWORD PTR tv905[rsp] 002e4 41 0f af fe imul edi, r14d 002e8 4d 8b 30 mov r14, QWORD PTR [r8] 002eb 44 0f af e5 imul r12d, ebp 002ef 4c 63 ed movsxd r13, ebp 002f2 03 7c 24 48 add edi, DWORD PTR tv900[rsp] 002f6 0f af fd imul edi, ebp 002f9 0f af dd imul ebx, ebp 002fc 0f 1f 40 00 npad 4 $LL10@stbi__crea: 00300 48 8b 44 24 68 mov rax, QWORD PTR final$1$[rsp] 00305 48 63 d6 movsxd rdx, esi 00308 49 03 50 18 add rdx, QWORD PTR [r8+24] 0030c 44 8b c7 mov r8d, edi 0030f 45 0f af 06 imul r8d, DWORD PTR [r14] 00313 48 63 cb movsxd rcx, ebx 00316 49 03 c0 add rax, r8 00319 4d 8b c5 mov r8, r13 0031c 48 03 c8 add rcx, rax 0031f e8 00 00 00 00 call memcpy 00324 4c 8b 84 24 50 01 00 00 mov r8, QWORD PTR a$[rsp] 0032c 03 f5 add esi, ebp 0032e 41 03 dc add ebx, r12d 00331 49 83 ef 01 sub r15, 1 00335 75 c9 jne SHORT $LL10@stbi__crea 00337 44 8b b4 24 80 01 00 00 mov r14d, DWORD PTR j$1$[rsp] 0033f 44 8b 6c 24 40 mov r13d, DWORD PTR tv892[rsp] 00344 44 8b 7c 24 54 mov r15d, DWORD PTR x$1$[rsp] 00349 8b 7c 24 58 mov edi, DWORD PTR y$1$[rsp] 0034d 8b 44 24 5c mov eax, DWORD PTR tv890[rsp] 00351 8b 74 24 60 mov esi, DWORD PTR tv901[rsp] $LN5@stbi__crea: ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { 00355 41 ff c6 inc r14d 00358 44 03 e8 add r13d, eax 0035b 44 89 b4 24 80 01 00 00 mov DWORD PTR j$1$[rsp], r14d 00363 44 89 6c 24 40 mov DWORD PTR tv892[rsp], r13d 00368 44 3b f7 cmp r14d, edi 0036b 0f 8c 54 ff ff ff jl $LL7@stbi__crea 00371 8b 5c 24 64 mov ebx, DWORD PTR img_len$1$[rsp] 00375 4c 8b a4 24 50 01 00 00 mov r12, QWORD PTR a$[rsp] 0037d 4c 8b 6c 24 70 mov r13, QWORD PTR tv889[rsp] $LN6@stbi__crea: ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); 00382 49 8b 4c 24 18 mov rcx, QWORD PTR [r12+24] 00387 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; 0038d 44 8b b4 24 60 01 00 00 mov r14d, DWORD PTR image_data_len$[rsp] 00395 44 8b 4c 24 44 mov r9d, DWORD PTR p$1$[rsp] 0039a 44 2b f3 sub r14d, ebx 0039d 8b c3 mov eax, ebx 0039f 48 01 84 24 58 01 00 00 add QWORD PTR image_data$[rsp], rax 003a7 33 db xor ebx, ebx 003a9 44 89 b4 24 60 01 00 00 mov DWORD PTR image_data_len$[rsp], r14d $LN2@stbi__crea: ; 4384 : for (p = 0; p < 7; ++p) { 003b1 41 ff c1 inc r9d 003b4 49 83 c5 04 add r13, 4 003b8 44 89 4c 24 44 mov DWORD PTR p$1$[rsp], r9d 003bd 4c 89 6c 24 70 mov QWORD PTR tv889[rsp], r13 003c2 41 83 f9 07 cmp r9d, 7 003c6 0f 8c 54 fd ff ff jl $LL4@stbi__crea ; 4410 : } ; 4411 : } ; 4412 : a->out = final; 003cc 48 8b 44 24 68 mov rax, QWORD PTR final$1$[rsp] 003d1 49 89 44 24 18 mov QWORD PTR [r12+24], rax ; 4413 : ; 4414 : return 1; 003d6 b8 01 00 00 00 mov eax, 1 $LN76@stbi__crea: 003db 4c 8b ac 24 10 01 00 00 mov r13, QWORD PTR [rsp+272] 003e3 4c 8b bc 24 08 01 00 00 mov r15, QWORD PTR [rsp+264] $LN74@stbi__crea: 003eb 48 8b b4 24 18 01 00 00 mov rsi, QWORD PTR [rsp+280] ; 4415 : } 003f3 48 81 c4 20 01 00 00 add rsp, 288 ; 00000120H 003fa 41 5e pop r14 003fc 41 5c pop r12 003fe 5f pop rdi 003ff 5d pop rbp 00400 5b pop rbx 00401 c3 ret 0 $LN43@stbi__crea: ; 4396 : STBI_FREE(final); 00402 48 8b 4c 24 68 mov rcx, QWORD PTR final$1$[rsp] 00407 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4397 : return 0; 0040d 33 c0 xor eax, eax 0040f eb ca jmp SHORT $LN76@stbi__crea $LN53@stbi__crea: ; 431 : stbi__g_failure_reason = str; 00411 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0041a 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00420 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 00425 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 00429 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00430 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); 00434 33 c0 xor eax, eax 00436 eb b3 jmp SHORT $LN74@stbi__crea stbi__create_png_image ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__compute_transparency _TEXT SEGMENT z$ = 8 tc$ = 16 out_n$ = 24 stbi__compute_transparency PROC ; COMDAT ; 4419 : stbi__context* s = z->s; 00000 48 8b 01 mov rax, QWORD PTR [rcx] ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; 00003 44 8b 48 04 mov r9d, DWORD PTR [rax+4] 00007 44 0f af 08 imul r9d, DWORD PTR [rax] ; 4421 : stbi_uc* p = z->out; 0000b 48 8b 41 18 mov rax, QWORD PTR [rcx+24] ; 4428 : for (i = 0; i < pixel_count; ++i) { 0000f 45 85 c9 test r9d, r9d 00012 74 67 je SHORT $LN20@stbi__comp ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { 00014 41 83 f8 02 cmp r8d, 2 00018 75 35 jne SHORT $LN8@stbi__comp ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); 0001a 44 0f b6 02 movzx r8d, BYTE PTR [rdx] 0001e 41 8b d1 mov edx, r9d 00021 45 33 c9 xor r9d, r9d 00024 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__comp: 00030 44 38 00 cmp BYTE PTR [rax], r8b ; 4430 : p += 2; 00033 48 8d 40 02 lea rax, QWORD PTR [rax+2] 00037 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH 0003c 41 0f 44 c9 cmove ecx, r9d 00040 88 48 ff mov BYTE PTR [rax-1], cl 00043 48 83 ea 01 sub rdx, 1 00047 75 e7 jne SHORT $LL4@stbi__comp ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } 00049 b8 01 00 00 00 mov eax, 1 0004e c3 ret 0 $LN8@stbi__comp: ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) 0004f 44 0f b6 12 movzx r10d, BYTE PTR [rdx] 00053 45 8b c1 mov r8d, r9d $LL7@stbi__comp: 00056 44 38 10 cmp BYTE PTR [rax], r10b 00059 75 16 jne SHORT $LN10@stbi__comp 0005b 0f b6 4a 01 movzx ecx, BYTE PTR [rdx+1] 0005f 38 48 01 cmp BYTE PTR [rax+1], cl 00062 75 0d jne SHORT $LN10@stbi__comp 00064 0f b6 4a 02 movzx ecx, BYTE PTR [rdx+2] 00068 38 48 02 cmp BYTE PTR [rax+2], cl 0006b 75 04 jne SHORT $LN10@stbi__comp ; 4436 : p[3] = 0; 0006d c6 40 03 00 mov BYTE PTR [rax+3], 0 $LN10@stbi__comp: ; 4437 : p += 4; 00071 48 83 c0 04 add rax, 4 00075 49 83 e8 01 sub r8, 1 00079 75 db jne SHORT $LL7@stbi__comp $LN20@stbi__comp: ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } 0007b b8 01 00 00 00 mov eax, 1 00080 c3 ret 0 stbi__compute_transparency ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__compute_transparency16 _TEXT SEGMENT z$ = 8 tc$ = 16 out_n$ = 24 stbi__compute_transparency16 PROC ; COMDAT ; 4445 : stbi__context* s = z->s; 00000 48 8b 01 mov rax, QWORD PTR [rcx] ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; 00003 44 8b 48 04 mov r9d, DWORD PTR [rax+4] 00007 44 0f af 08 imul r9d, DWORD PTR [rax] ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; 0000b 48 8b 41 18 mov rax, QWORD PTR [rcx+24] ; 4454 : for (i = 0; i < pixel_count; ++i) { 0000f 45 85 c9 test r9d, r9d 00012 74 75 je SHORT $LN20@stbi__comp ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { 00014 41 83 f8 02 cmp r8d, 2 00018 75 36 jne SHORT $LN8@stbi__comp ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); 0001a 44 0f b7 02 movzx r8d, WORD PTR [rdx] 0001e 41 8b d1 mov edx, r9d 00021 45 33 c9 xor r9d, r9d 00024 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__comp: 00030 66 44 39 00 cmp WORD PTR [rax], r8w ; 4456 : p += 2; 00034 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00038 b9 ff ff 00 00 mov ecx, 65535 ; 0000ffffH 0003d 66 41 0f 44 c9 cmove cx, r9w 00042 66 89 48 fe mov WORD PTR [rax-2], cx 00046 48 83 ea 01 sub rdx, 1 0004a 75 e4 jne SHORT $LL4@stbi__comp ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } 0004c 8d 42 01 lea eax, QWORD PTR [rdx+1] 0004f c3 ret 0 $LN8@stbi__comp: ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) 00050 44 0f b7 12 movzx r10d, WORD PTR [rdx] 00054 45 8b c1 mov r8d, r9d 00057 45 33 c9 xor r9d, r9d 0005a 66 0f 1f 44 00 00 npad 6 $LL7@stbi__comp: 00060 66 44 39 10 cmp WORD PTR [rax], r10w 00064 75 19 jne SHORT $LN10@stbi__comp 00066 0f b7 4a 02 movzx ecx, WORD PTR [rdx+2] 0006a 66 39 48 02 cmp WORD PTR [rax+2], cx 0006e 75 0f jne SHORT $LN10@stbi__comp 00070 0f b7 4a 04 movzx ecx, WORD PTR [rdx+4] 00074 66 39 48 04 cmp WORD PTR [rax+4], cx 00078 75 05 jne SHORT $LN10@stbi__comp ; 4462 : p[3] = 0; 0007a 66 44 89 48 06 mov WORD PTR [rax+6], r9w $LN10@stbi__comp: ; 4463 : p += 4; 0007f 48 83 c0 08 add rax, 8 00083 49 83 e8 01 sub r8, 1 00087 75 d7 jne SHORT $LL7@stbi__comp $LN20@stbi__comp: ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } 00089 b8 01 00 00 00 mov eax, 1 0008e c3 ret 0 stbi__compute_transparency16 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__expand_png_palette _TEXT SEGMENT a$ = 64 palette$ = 72 len$dead$ = 80 pal_img_n$ = 88 stbi__expand_png_palette PROC ; COMDAT ; 4470 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 57 push rdi 00010 41 56 push r14 00012 41 57 push r15 00014 48 83 ec 20 sub rsp, 32 ; 00000020H ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; 00018 48 8b 01 mov rax, QWORD PTR [rcx] 0001b 41 8b e9 mov ebp, r9d ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; 0001e 48 8b 59 18 mov rbx, QWORD PTR [rcx+24] 00022 48 8b fa mov rdi, rdx 00025 4c 8b f9 mov r15, rcx 00028 8b 70 04 mov esi, DWORD PTR [rax+4] 0002b 0f af 30 imul esi, DWORD PTR [rax] ; 467 : if (a < 0 || b < 0) return 0; 0002e 85 f6 test esi, esi 00030 0f 88 bf 00 00 00 js $LN40@stbi__expa 00036 45 85 c9 test r9d, r9d 00039 0f 88 b6 00 00 00 js $LN40@stbi__expa ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0003f 74 11 je SHORT $LN13@stbi__expa ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00041 33 d2 xor edx, edx 00043 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00048 f7 f5 div ebp ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0004a 3b f0 cmp esi, eax 0004c 0f 8f a3 00 00 00 jg $LN40@stbi__expa $LN13@stbi__expa: ; 502 : return stbi__malloc(a * b + add); 00052 8b c6 mov eax, esi 00054 0f af c5 imul eax, ebp 00057 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 0005a ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00060 4c 8b f0 mov r14, rax ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); 00063 48 85 c0 test rax, rax 00066 0f 84 89 00 00 00 je $LN40@stbi__expa ; 4481 : for (i = 0; i < pixel_count; ++i) { 0006c 85 f6 test esi, esi 0006e 74 70 je SHORT $LN6@stbi__expa ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { 00070 44 8b c6 mov r8d, esi 00073 48 8d 50 02 lea rdx, QWORD PTR [rax+2] 00077 83 fd 03 cmp ebp, 3 0007a 75 34 jne SHORT $LL7@stbi__expa 0007c 0f 1f 40 00 npad 4 $LL4@stbi__expa: ; 4482 : int n = orig[i] * 4; 00080 0f b6 0b movzx ecx, BYTE PTR [rbx] ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; 00083 48 8d 52 03 lea rdx, QWORD PTR [rdx+3] 00087 48 8d 5b 01 lea rbx, QWORD PTR [rbx+1] 0008b 0f b6 04 8f movzx eax, BYTE PTR [rdi+rcx*4] 0008f 88 42 fb mov BYTE PTR [rdx-5], al 00092 0f b6 44 8f 01 movzx eax, BYTE PTR [rdi+rcx*4+1] 00097 0f b6 4c 8f 02 movzx ecx, BYTE PTR [rdi+rcx*4+2] 0009c 88 4a fd mov BYTE PTR [rdx-3], cl 0009f 88 42 fc mov BYTE PTR [rdx-4], al 000a2 49 83 e8 01 sub r8, 1 000a6 75 d8 jne SHORT $LL4@stbi__expa ; 4487 : } ; 4488 : } 000a8 eb 36 jmp SHORT $LN6@stbi__expa 000aa 66 0f 1f 44 00 00 npad 6 $LL7@stbi__expa: ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; 000b0 0f b6 0b movzx ecx, BYTE PTR [rbx] ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; 000b3 48 8d 52 04 lea rdx, QWORD PTR [rdx+4] 000b7 48 8d 5b 01 lea rbx, QWORD PTR [rbx+1] 000bb 0f b6 04 8f movzx eax, BYTE PTR [rdi+rcx*4] 000bf 88 42 fa mov BYTE PTR [rdx-6], al 000c2 0f b6 44 8f 01 movzx eax, BYTE PTR [rdi+rcx*4+1] 000c7 88 42 fb mov BYTE PTR [rdx-5], al 000ca 0f b6 44 8f 02 movzx eax, BYTE PTR [rdi+rcx*4+2] 000cf 0f b6 4c 8f 03 movzx ecx, BYTE PTR [rdi+rcx*4+3] 000d4 88 4a fd mov BYTE PTR [rdx-3], cl 000d7 88 42 fc mov BYTE PTR [rdx-4], al 000da 49 83 e8 01 sub r8, 1 000de 75 d0 jne SHORT $LL7@stbi__expa $LN6@stbi__expa: ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); 000e0 49 8b 4f 18 mov rcx, QWORD PTR [r15+24] 000e4 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; 000ea b8 01 00 00 00 mov eax, 1 000ef 4d 89 77 18 mov QWORD PTR [r15+24], r14 000f3 eb 25 jmp SHORT $LN1@stbi__expa $LN40@stbi__expa: ; 431 : stbi__g_failure_reason = str; 000f5 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000fe 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00104 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 00109 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 0010d 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00114 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); 00118 33 c0 xor eax, eax $LN1@stbi__expa: ; 4505 : } 0011a 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 0011f 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 00124 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 00129 48 83 c4 20 add rsp, 32 ; 00000020H 0012d 41 5f pop r15 0012f 41 5e pop r14 00131 5f pop rdi 00132 c3 ret 0 stbi__expand_png_palette ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__de_iphone _TEXT SEGMENT z$ = 16 stbi__de_iphone PROC ; COMDAT ; 4548 : { 00000 48 83 ec 08 sub rsp, 8 ; 4549 : stbi__context* s = z->s; 00004 48 8b 01 mov rax, QWORD PTR [rcx] ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; 00007 48 8b 49 18 mov rcx, QWORD PTR [rcx+24] 0000b 44 8b 40 04 mov r8d, DWORD PTR [rax+4] 0000f 44 0f af 00 imul r8d, DWORD PTR [rax] ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb 00013 83 78 0c 03 cmp DWORD PTR [rax+12], 3 00017 75 32 jne SHORT $LN11@stbi__de_i ; 4554 : for (i = 0; i < pixel_count; ++i) { 00019 45 85 c0 test r8d, r8d 0001c 0f 84 f4 00 00 00 je $LN9@stbi__de_i 00022 0f 1f 40 00 66 66 0f 1f 84 00 00 00 00 00 npad 14 $LL4@stbi__de_i: ; 4555 : stbi_uc t = p[0]; 00030 0f b6 11 movzx edx, BYTE PTR [rcx] ; 4556 : p[0] = p[2]; 00033 0f b6 41 02 movzx eax, BYTE PTR [rcx+2] 00037 88 01 mov BYTE PTR [rcx], al ; 4557 : p[2] = t; 00039 88 51 02 mov BYTE PTR [rcx+2], dl ; 4558 : p += 3; 0003c 48 8d 49 03 lea rcx, QWORD PTR [rcx+3] 00040 49 83 e8 01 sub r8, 1 00044 75 ea jne SHORT $LL4@stbi__de_i ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } 00046 48 83 c4 08 add rsp, 8 0004a c3 ret 0 $LN11@stbi__de_i: ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { 0004b 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00051 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0005a 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0005e ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__unpremultiply_on_load_set 00063 83 3c 02 00 cmp DWORD PTR [rdx+rax], 0 00067 74 0a je SHORT $LN18@stbi__de_i 00069 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__unpremultiply_on_load_local 0006e 8b 04 02 mov eax, DWORD PTR [rdx+rax] 00071 eb 06 jmp SHORT $LN19@stbi__de_i $LN18@stbi__de_i: 00073 8b 05 00 00 00 00 mov eax, DWORD PTR stbi__unpremultiply_on_load_global $LN19@stbi__de_i: ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { 00079 45 85 c0 test r8d, r8d 0007c 0f 84 94 00 00 00 je $LN9@stbi__de_i ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { 00082 85 c0 test eax, eax 00084 74 7a je SHORT $LL10@stbi__de_i 00086 48 89 1c 24 mov QWORD PTR [rsp], rbx ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { 0008a 45 8b d0 mov r10d, r8d 0008d 0f 1f 00 npad 3 $LL7@stbi__de_i: ; 4566 : stbi_uc a = p[3]; 00090 0f b6 41 03 movzx eax, BYTE PTR [rcx+3] ; 4567 : stbi_uc t = p[0]; 00094 44 0f b6 19 movzx r11d, BYTE PTR [rcx] 00098 0f b6 59 02 movzx ebx, BYTE PTR [rcx+2] ; 4568 : if (a) { 0009c 84 c0 test al, al 0009e 74 40 je SHORT $LN15@stbi__de_i ; 4569 : stbi_uc half = a / 2; 000a0 44 8b c0 mov r8d, eax 000a3 44 8b c8 mov r9d, eax ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; 000a6 0f b6 41 01 movzx eax, BYTE PTR [rcx+1] 000aa 33 d2 xor edx, edx 000ac 69 c0 ff 00 00 00 imul eax, eax, 255 ; 000000ffH 000b2 41 d1 e8 shr r8d, 1 000b5 41 03 c0 add eax, r8d 000b8 41 f7 f1 div r9d ; 4572 : p[2] = (t * 255 + half) / a; 000bb 33 d2 xor edx, edx 000bd 88 41 01 mov BYTE PTR [rcx+1], al 000c0 41 69 c3 ff 00 00 00 imul eax, r11d, 255 ; 000000ffH 000c7 41 03 c0 add eax, r8d 000ca 41 f7 f1 div r9d 000cd 33 d2 xor edx, edx 000cf 44 8b d8 mov r11d, eax 000d2 69 c3 ff 00 00 00 imul eax, ebx, 255 ; 000000ffH 000d8 41 03 c0 add eax, r8d 000db 41 f7 f1 div r9d ; 4573 : } 000de eb 03 jmp SHORT $LN16@stbi__de_i $LN15@stbi__de_i: ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; 000e0 0f b6 c3 movzx eax, bl $LN16@stbi__de_i: ; 4577 : } ; 4578 : p += 4; 000e3 88 01 mov BYTE PTR [rcx], al 000e5 44 88 59 02 mov BYTE PTR [rcx+2], r11b 000e9 48 83 c1 04 add rcx, 4 000ed 49 83 ea 01 sub r10, 1 000f1 75 9d jne SHORT $LL7@stbi__de_i ; 4579 : } ; 4580 : } 000f3 48 8b 1c 24 mov rbx, QWORD PTR [rsp] ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } 000f7 48 83 c4 08 add rsp, 8 000fb c3 ret 0 000fc 0f 1f 40 00 npad 4 $LL10@stbi__de_i: ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; 00100 0f b6 11 movzx edx, BYTE PTR [rcx] ; 4585 : p[0] = p[2]; 00103 0f b6 41 02 movzx eax, BYTE PTR [rcx+2] 00107 88 01 mov BYTE PTR [rcx], al ; 4586 : p[2] = t; 00109 88 51 02 mov BYTE PTR [rcx+2], dl ; 4587 : p += 4; 0010c 48 8d 49 04 lea rcx, QWORD PTR [rcx+4] 00110 49 83 e8 01 sub r8, 1 00114 75 ea jne SHORT $LL10@stbi__de_i $LN9@stbi__de_i: ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } 00116 48 83 c4 08 add rsp, 8 0011a c3 ret 0 stbi__de_iphone ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__parse_png_file _TEXT SEGMENT pal_img_n$1$ = 64 has_trans$1$ = 65 first$1$ = 68 ioff$1$ = 72 interlace$1$ = 76 is_iphone$1$ = 80 color$1$ = 84 req_comp$1$ = 88 c$14 = 96 a$15 = 112 tc$ = 4208 tc16$ = 4212 palette$ = 4224 __$ArrayPad$ = 5248 z$ = 5312 scan$dead$ = 5320 req_comp$ = 5328 stbi__parse_png_file PROC ; COMDAT ; 4596 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000a 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 0000f 55 push rbp 00010 41 54 push r12 00012 41 55 push r13 00014 41 56 push r14 00016 41 57 push r15 00018 48 8d ac 24 70 ec ff ff lea rbp, QWORD PTR [rsp-5008] 00020 b8 90 14 00 00 mov eax, 5264 ; 00001490H 00025 e8 00 00 00 00 call __chkstk 0002a 48 2b e0 sub rsp, rax 0002d 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00034 48 33 c4 xor rax, rsp 00037 48 89 85 80 13 00 00 mov QWORD PTR __$ArrayPad$[rbp-256], rax 0003e 4c 8b e9 mov r13, rcx 00041 44 89 44 24 58 mov DWORD PTR req_comp$1$[rsp], r8d ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; 00046 33 c9 xor ecx, ecx 00048 c6 44 24 40 00 mov BYTE PTR pal_img_n$1$[rsp], 0 0004d 33 c0 xor eax, eax 0004f 89 4c 24 48 mov DWORD PTR ioff$1$[rsp], ecx 00053 45 32 f6 xor r14b, r14b ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; 00056 89 4c 24 4c mov DWORD PTR interlace$1$[rsp], ecx ; 4602 : stbi__context* s = z->s; 0005a 49 8b 5d 00 mov rbx, QWORD PTR [r13] 0005e 44 8b f9 mov r15d, ecx 00061 44 8b e1 mov r12d, ecx 00064 89 4c 24 54 mov DWORD PTR color$1$[rsp], ecx 00068 89 4c 24 50 mov DWORD PTR is_iphone$1$[rsp], ecx ; 4603 : ; 4604 : z->expanded = NULL; 0006c 49 89 4d 10 mov QWORD PTR [r13+16], rcx ; 4605 : z->idata = NULL; 00070 49 89 4d 08 mov QWORD PTR [r13+8], rcx ; 4606 : z->out = NULL; 00074 49 89 4d 18 mov QWORD PTR [r13+24], rcx 00078 44 88 74 24 41 mov BYTE PTR has_trans$1$[rsp], r14b 0007d 44 8b f1 mov r14d, ecx ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; 00080 48 8b cb mov rcx, rbx 00083 66 89 85 70 0f 00 00 mov WORD PTR tc$[rbp-256], ax 0008a 88 85 72 0f 00 00 mov BYTE PTR tc$[rbp-254], al 00090 c7 44 24 44 01 00 00 00 mov DWORD PTR first$1$[rsp], 1 00098 e8 00 00 00 00 call stbi__check_png_header 0009d 85 c0 test eax, eax 0009f 0f 84 4b 0e 00 00 je $LN327@stbi__pars $LL2@stbi__pars: ; 1168 : stbi__uint32 z = stbi__get16be(s); 000a5 48 8b cb mov rcx, rbx 000a8 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 000ad 48 8b cb mov rcx, rbx 000b0 8b f0 mov esi, eax 000b2 e8 00 00 00 00 call stbi__get16be 000b7 c1 e6 10 shl esi, 16 ; 1168 : stbi__uint32 z = stbi__get16be(s); 000ba 48 8b cb mov rcx, rbx ; 1169 : return (z << 16) + stbi__get16be(s); 000bd 03 f0 add esi, eax ; 4098 : c.length = stbi__get32be(s); 000bf 89 74 24 60 mov DWORD PTR c$14[rsp], esi ; 1168 : stbi__uint32 z = stbi__get16be(s); 000c3 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 000c8 48 8b cb mov rcx, rbx 000cb 8b f8 mov edi, eax 000cd e8 00 00 00 00 call stbi__get16be 000d2 c1 e7 10 shl edi, 16 000d5 8d 14 07 lea edx, DWORD PTR [rdi+rax] ; 4099 : c.type = stbi__get32be(s); 000d8 89 54 24 64 mov DWORD PTR c$14[rsp+4], edx ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); 000dc 48 8b 44 24 60 mov rax, QWORD PTR c$14[rsp] ; 4614 : switch (c.type) { 000e1 48 8b c8 mov rcx, rax 000e4 48 c1 e9 20 shr rcx, 32 ; 00000020H 000e8 81 f9 52 44 48 49 cmp ecx, 1229472850 ; 49484452H 000ee 0f 87 80 03 00 00 ja $LN99@stbi__pars 000f4 0f 84 fd 00 00 00 je $LN24@stbi__pars 000fa 81 f9 49 42 67 43 cmp ecx, 1130840649 ; 43674249H 00100 0f 84 e4 00 00 00 je $LN23@stbi__pars 00106 81 f9 54 41 44 49 cmp ecx, 1229209940 ; 49444154H 0010c 74 43 je SHORT $LN61@stbi__pars 0010e 81 f9 44 4e 45 49 cmp ecx, 1229278788 ; 49454e44H 00114 0f 85 6e 03 00 00 jne $LN93@stbi__pars ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); 0011a 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 0011f 0f 85 a8 0d 00 00 jne $LN354@stbi__pars ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); 00125 49 8b 7d 08 mov rdi, QWORD PTR [r13+8] 00129 48 85 ff test rdi, rdi 0012c 0f 85 77 06 00 00 jne $LN75@stbi__pars ; 431 : stbi__g_failure_reason = str; 00132 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00138 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00141 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00145 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07MLPECBNA@no?5IDAT@ ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); 0014c e9 96 0d 00 00 jmp $LN635@stbi__pars $LN61@stbi__pars: ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); 00151 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 00156 0f 85 71 0d 00 00 jne $LN354@stbi__pars ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); 0015c 80 7c 24 40 00 cmp BYTE PTR pal_img_n$1$[rsp], 0 00161 74 09 je SHORT $LN63@stbi__pars 00163 45 85 ff test r15d, r15d 00166 0f 84 18 0b 00 00 je $LN324@stbi__pars $LN63@stbi__pars: ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); 0016c 81 fe 00 00 00 40 cmp esi, 1073741824 ; 40000000H 00172 0f 87 69 0b 00 00 ja $LN326@stbi__pars ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; 00178 8b 7c 24 48 mov edi, DWORD PTR ioff$1$[rsp] 0017c 8d 0c 3e lea ecx, DWORD PTR [rsi+rdi] 0017f 3b cf cmp ecx, edi 00181 0f 8c 69 0d 00 00 jl $LN327@stbi__pars ; 4702 : if (ioff + c.length > idata_limit) { 00187 41 3b ce cmp ecx, r14d 0018a 76 39 jbe SHORT $LN479@stbi__pars ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; 0018c 45 85 f6 test r14d, r14d 0018f 75 0d jne SHORT $LN318@stbi__pars 00191 41 be 00 10 00 00 mov r14d, 4096 ; 00001000H 00197 41 3b f6 cmp esi, r14d 0019a 44 0f 47 f0 cmova r14d, eax $LN318@stbi__pars: ; 4706 : while (ioff + c.length > idata_limit) 0019e 41 3b ce cmp ecx, r14d 001a1 76 08 jbe SHORT $LN20@stbi__pars $LL19@stbi__pars: ; 4707 : idata_limit *= 2; 001a3 45 03 f6 add r14d, r14d 001a6 41 3b ce cmp ecx, r14d 001a9 77 f8 ja SHORT $LL19@stbi__pars $LN20@stbi__pars: ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); 001ab 49 8b 4d 08 mov rcx, QWORD PTR [r13+8] 001af 41 8b d6 mov edx, r14d 001b2 ff 15 00 00 00 00 call QWORD PTR __imp_realloc 001b8 48 85 c0 test rax, rax 001bb 0f 84 e2 0a 00 00 je $LN328@stbi__pars ; 4710 : z->idata = p; 001c1 49 89 45 08 mov QWORD PTR [r13+8], rax $LN479@stbi__pars: ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); 001c5 48 8b d7 mov rdx, rdi 001c8 44 8b c6 mov r8d, esi 001cb 49 03 55 08 add rdx, QWORD PTR [r13+8] 001cf 48 8b cb mov rcx, rbx 001d2 e8 00 00 00 00 call stbi__getn 001d7 85 c0 test eax, eax 001d9 0f 84 e3 0a 00 00 je $LN329@stbi__pars ; 4713 : ioff += c.length; 001df 03 fe add edi, esi 001e1 89 7c 24 48 mov DWORD PTR ioff$1$[rsp], edi ; 4714 : break; 001e5 e9 aa 05 00 00 jmp $LN8@stbi__pars $LN23@stbi__pars: ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; 001ea c7 44 24 50 01 00 00 00 mov DWORD PTR is_iphone$1$[rsp], 1 ; 1110 : return; 001f2 e9 a6 02 00 00 jmp $LN634@stbi__pars $LN24@stbi__pars: ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); 001f7 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 001fc 0f 84 d7 0b 00 00 je $LN330@stbi__pars ; 4622 : first = 0; 00202 33 c0 xor eax, eax 00204 89 44 24 44 mov DWORD PTR first$1$[rsp], eax 00208 83 fe 0d cmp esi, 13 ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); 0020b 0f 85 a9 0b 00 00 jne $LN331@stbi__pars ; 1168 : stbi__uint32 z = stbi__get16be(s); 00211 48 8b cb mov rcx, rbx 00214 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00219 48 8b cb mov rcx, rbx 0021c 8b f8 mov edi, eax 0021e e8 00 00 00 00 call stbi__get16be 00223 c1 e7 10 shl edi, 16 ; 1168 : stbi__uint32 z = stbi__get16be(s); 00226 48 8b cb mov rcx, rbx ; 1169 : return (z << 16) + stbi__get16be(s); 00229 03 c7 add eax, edi ; 4624 : s->img_x = stbi__get32be(s); 0022b 89 03 mov DWORD PTR [rbx], eax ; 1168 : stbi__uint32 z = stbi__get16be(s); 0022d e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00232 48 8b cb mov rcx, rbx 00235 8b f8 mov edi, eax 00237 e8 00 00 00 00 call stbi__get16be 0023c c1 e7 10 shl edi, 16 0023f 03 c7 add eax, edi ; 4625 : s->img_y = stbi__get32be(s); 00241 89 43 04 mov DWORD PTR [rbx+4], eax ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 00244 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 00249 0f 87 f2 01 00 00 ja $LN342@stbi__pars ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 0024f 81 3b 00 00 00 01 cmp DWORD PTR [rbx], 16777216 ; 01000000H 00255 0f 87 e6 01 00 00 ja $LN342@stbi__pars ; 1077 : if (s->img_buffer < s->img_buffer_end) 0025b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00262 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00269 73 0f jae SHORT $LN161@stbi__pars ; 1078 : return *s->img_buffer++; 0026b 0f b6 08 movzx ecx, BYTE PTR [rax] 0026e 48 ff c0 inc rax 00271 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00278 eb 26 jmp SHORT $LN160@stbi__pars $LN161@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 0027a 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0027e 74 1e je SHORT $LN162@stbi__pars ; 1080 : stbi__refill_buffer(s); 00280 48 8b cb mov rcx, rbx 00283 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00288 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0028f 0f b6 08 movzx ecx, BYTE PTR [rax] 00292 48 ff c0 inc rax 00295 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0029c eb 02 jmp SHORT $LN160@stbi__pars $LN162@stbi__pars: ; 1082 : } ; 1083 : return 0; 0029e 32 c9 xor cl, cl $LN160@stbi__pars: ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); 002a0 0f b6 c1 movzx eax, cl 002a3 41 89 45 20 mov DWORD PTR [r13+32], eax 002a7 83 f8 10 cmp eax, 16 002aa 0f 87 eb 0a 00 00 ja $LN334@stbi__pars 002b0 b9 16 01 01 00 mov ecx, 65814 ; 00010116H 002b5 0f a3 c1 bt ecx, eax 002b8 0f 83 dd 0a 00 00 jae $LN334@stbi__pars ; 1077 : if (s->img_buffer < s->img_buffer_end) 002be 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002c5 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 002cc 73 0f jae SHORT $LN167@stbi__pars ; 1078 : return *s->img_buffer++; 002ce 0f b6 08 movzx ecx, BYTE PTR [rax] 002d1 48 ff c0 inc rax 002d4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002db eb 26 jmp SHORT $LN166@stbi__pars $LN167@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 002dd 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 002e1 74 1e je SHORT $LN168@stbi__pars ; 1080 : stbi__refill_buffer(s); 002e3 48 8b cb mov rcx, rbx 002e6 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002eb 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002f2 0f b6 08 movzx ecx, BYTE PTR [rax] 002f5 48 ff c0 inc rax 002f8 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002ff eb 02 jmp SHORT $LN166@stbi__pars $LN168@stbi__pars: ; 1082 : } ; 1083 : return 0; 00301 32 c9 xor cl, cl $LN166@stbi__pars: ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); 00303 0f b6 f9 movzx edi, cl 00306 89 7c 24 54 mov DWORD PTR color$1$[rsp], edi 0030a 83 ff 06 cmp edi, 6 0030d 0f 87 ed 09 00 00 ja $LN336@stbi__pars ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); 00313 83 ff 03 cmp edi, 3 00316 75 16 jne SHORT $LN32@stbi__pars 00318 41 83 7d 20 10 cmp DWORD PTR [r13+32], 16 0031d 0f 84 dd 09 00 00 je $LN336@stbi__pars ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); 00323 40 0f b6 f7 movzx esi, dil 00327 40 88 7c 24 40 mov BYTE PTR pal_img_n$1$[rsp], dil 0032c eb 0f jmp SHORT $LN34@stbi__pars $LN32@stbi__pars: 0032e 40 f6 c7 01 test dil, 1 00332 0f 85 c8 09 00 00 jne $LN336@stbi__pars 00338 0f b6 74 24 40 movzx esi, BYTE PTR pal_img_n$1$[rsp] $LN34@stbi__pars: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0033d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00344 72 15 jb SHORT $LN632@stbi__pars ; 1079 : if (s->read_from_callbacks) { 00346 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0034a 74 24 je SHORT $LN184@stbi__pars ; 1080 : stbi__refill_buffer(s); 0034c 48 8b cb mov rcx, rbx 0034f e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00354 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN632@stbi__pars: ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); 0035b 0f b6 08 movzx ecx, BYTE PTR [rax] 0035e 48 ff c0 inc rax 00361 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00368 84 c9 test cl, cl 0036a 0f 85 af 09 00 00 jne $LN338@stbi__pars $LN184@stbi__pars: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00370 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00377 72 15 jb SHORT $LN633@stbi__pars ; 1079 : if (s->read_from_callbacks) { 00379 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0037d 74 24 je SHORT $LN206@stbi__pars ; 1080 : stbi__refill_buffer(s); 0037f 48 8b cb mov rcx, rbx 00382 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00387 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN633@stbi__pars: ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); 0038e 0f b6 08 movzx ecx, BYTE PTR [rax] 00391 48 ff c0 inc rax 00394 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0039b 84 c9 test cl, cl 0039d 0f 85 9b 09 00 00 jne $LN339@stbi__pars $LN206@stbi__pars: ; 1077 : if (s->img_buffer < s->img_buffer_end) 003a3 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 003aa 73 0f jae SHORT $LN219@stbi__pars ; 1078 : return *s->img_buffer++; 003ac 0f b6 08 movzx ecx, BYTE PTR [rax] 003af 48 ff c0 inc rax 003b2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003b9 eb 26 jmp SHORT $LN218@stbi__pars $LN219@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 003bb 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 003bf 74 1e je SHORT $LN220@stbi__pars ; 1080 : stbi__refill_buffer(s); 003c1 48 8b cb mov rcx, rbx 003c4 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003c9 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 003d0 0f b6 08 movzx ecx, BYTE PTR [rax] 003d3 48 ff c0 inc rax 003d6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003dd eb 02 jmp SHORT $LN218@stbi__pars $LN220@stbi__pars: ; 1082 : } ; 1083 : return 0; 003df 32 c9 xor cl, cl $LN218@stbi__pars: ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); 003e1 44 0f b6 e1 movzx r12d, cl 003e5 44 89 64 24 4c mov DWORD PTR interlace$1$[rsp], r12d 003ea 41 83 fc 01 cmp r12d, 1 003ee 0f 87 88 09 00 00 ja $LN340@stbi__pars ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); 003f4 8b 0b mov ecx, DWORD PTR [rbx] 003f6 85 c9 test ecx, ecx 003f8 0f 84 5f 09 00 00 je $LN39@stbi__pars 003fe 44 8b 4b 04 mov r9d, DWORD PTR [rbx+4] 00402 45 85 c9 test r9d, r9d 00405 0f 84 52 09 00 00 je $LN39@stbi__pars ; 4636 : if (!pal_img_n) { 0040b 33 d2 xor edx, edx 0040d b8 00 00 00 40 mov eax, 1073741824 ; 40000000H 00412 f7 f1 div ecx 00414 40 84 f6 test sil, sil 00417 75 47 jne SHORT $LN40@stbi__pars ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); 00419 33 d2 xor edx, edx 0041b 44 8b c7 mov r8d, edi 0041e 41 c1 e8 02 shr r8d, 2 00422 8b cf mov ecx, edi 00424 83 e1 02 and ecx, 2 00427 41 83 e0 01 and r8d, 1 0042b 83 c9 01 or ecx, 1 0042e 44 03 c1 add r8d, ecx 00431 41 f7 f0 div r8d 00434 44 89 43 08 mov DWORD PTR [rbx+8], r8d 00438 41 3b c1 cmp eax, r9d 0043b 0f 83 53 03 00 00 jae $LN8@stbi__pars $LN342@stbi__pars: ; 4781 : } 00441 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00447 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00450 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00454 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 0045b e9 87 0a 00 00 jmp $LN635@stbi__pars $LN40@stbi__pars: ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); 00460 c1 e8 02 shr eax, 2 00463 c7 43 08 01 00 00 00 mov DWORD PTR [rbx+8], 1 0046a 41 3b c1 cmp eax, r9d 0046d 72 d2 jb SHORT $LN342@stbi__pars ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; 0046f e9 20 03 00 00 jmp $LN8@stbi__pars $LN99@stbi__pars: ; 4614 : switch (c.type) { 00474 81 f9 45 54 4c 50 cmp ecx, 1347179589 ; 504c5445H 0047a 0f 84 c4 01 00 00 je $LN44@stbi__pars 00480 81 f9 53 4e 52 74 cmp ecx, 1951551059 ; 74524e53H 00486 74 76 je SHORT $LN48@stbi__pars $LN93@stbi__pars: ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); 00488 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 0048d 0f 85 3a 0a 00 00 jne $LN354@stbi__pars ; 4764 : if ((c.type & (1 << 29)) == 0) { 00493 0f ba e2 1d bt edx, 29 00497 0f 83 5b 09 00 00 jae $LN345@stbi__pars $LN634@stbi__pars: ; 1168 : stbi__uint32 z = stbi__get16be(s); 0049d 85 f6 test esi, esi 0049f 0f 84 ef 02 00 00 je $LN8@stbi__pars 004a5 79 13 jns SHORT $LN144@stbi__pars 004a7 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 004ae 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004b5 e9 da 02 00 00 jmp $LN8@stbi__pars $LN144@stbi__pars: 004ba 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 004bf 74 2e je SHORT $LN481@stbi__pars 004c1 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 004c7 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] 004cd 3b ce cmp ecx, esi 004cf 7d 1e jge SHORT $LN481@stbi__pars 004d1 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 004d8 2b f1 sub esi, ecx 004da 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 004de 8b d6 mov edx, esi 004e0 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004e7 ff 53 18 call QWORD PTR [rbx+24] 004ea e9 a5 02 00 00 jmp $LN8@stbi__pars $LN481@stbi__pars: 004ef 48 63 c6 movsxd rax, esi 004f2 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax 004f9 e9 96 02 00 00 jmp $LN8@stbi__pars $LN48@stbi__pars: ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); 004fe 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 00503 0f 85 c4 09 00 00 jne $LN354@stbi__pars ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); 00509 49 83 7d 08 00 cmp QWORD PTR [r13+8], 0 0050e 0f 85 81 09 00 00 jne $LN347@stbi__pars ; 4667 : if (pal_img_n) { 00514 80 7c 24 40 00 cmp BYTE PTR pal_img_n$1$[rsp], 0 00519 0f 84 8f 00 00 00 je $LN51@stbi__pars ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); 0051f 45 85 ff test r15d, r15d 00522 0f 84 35 09 00 00 je $LN349@stbi__pars ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); 00528 41 3b f7 cmp esi, r15d 0052b 0f 87 0d 09 00 00 ja $LN350@stbi__pars ; 4671 : pal_img_n = 4; 00531 33 c0 xor eax, eax 00533 c6 44 24 40 04 mov BYTE PTR pal_img_n$1$[rsp], 4 00538 8b f8 mov edi, eax ; 4672 : for (i = 0; i < c.length; ++i) 0053a 85 f6 test esi, esi 0053c 0f 84 52 02 00 00 je $LN8@stbi__pars 00542 0f 1f 40 00 66 66 0f 1f 84 00 00 00 00 00 npad 14 $LL12@stbi__pars: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00550 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00557 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0055e 73 0f jae SHORT $LN171@stbi__pars ; 1078 : return *s->img_buffer++; 00560 0f b6 10 movzx edx, BYTE PTR [rax] 00563 48 ff c0 inc rax 00566 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0056d eb 26 jmp SHORT $LN170@stbi__pars $LN171@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 0056f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00573 74 1e je SHORT $LN172@stbi__pars ; 1080 : stbi__refill_buffer(s); 00575 48 8b cb mov rcx, rbx 00578 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0057d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00584 0f b6 10 movzx edx, BYTE PTR [rax] 00587 48 ff c0 inc rax 0058a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00591 eb 02 jmp SHORT $LN170@stbi__pars $LN172@stbi__pars: ; 1082 : } ; 1083 : return 0; 00593 32 d2 xor dl, dl $LN170@stbi__pars: ; 4673 : palette[i * 4 + 3] = stbi__get8(s); 00595 8d 04 bd 03 00 00 00 lea eax, DWORD PTR [rdi*4+3] 0059c ff c7 inc edi 0059e 88 94 05 80 0f 00 00 mov BYTE PTR palette$[rbp+rax-256], dl 005a5 3b fe cmp edi, esi 005a7 72 a7 jb SHORT $LL12@stbi__pars ; 4674 : } 005a9 e9 e6 01 00 00 jmp $LN8@stbi__pars $LN51@stbi__pars: ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); 005ae 8b 4b 08 mov ecx, DWORD PTR [rbx+8] 005b1 f6 c1 01 test cl, 1 005b4 0f 84 bf 08 00 00 je $LN351@stbi__pars ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); 005ba 8d 04 09 lea eax, DWORD PTR [rcx+rcx] 005bd 3b f0 cmp esi, eax 005bf 0f 85 79 08 00 00 jne $LN350@stbi__pars ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { 005c5 33 c0 xor eax, eax 005c7 c6 44 24 41 01 mov BYTE PTR has_trans$1$[rsp], 1 005cc 41 83 7d 20 10 cmp DWORD PTR [r13+32], 16 005d1 8b f0 mov esi, eax 005d3 75 2a jne SHORT $LN59@stbi__pars ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is 005d5 85 c9 test ecx, ecx 005d7 0f 8e b7 01 00 00 jle $LN8@stbi__pars 005dd 48 8d bd 74 0f 00 00 lea rdi, QWORD PTR tc16$[rbp-256] $LL15@stbi__pars: 005e4 48 8b cb mov rcx, rbx 005e7 e8 00 00 00 00 call stbi__get16be 005ec ff c6 inc esi 005ee 66 89 07 mov WORD PTR [rdi], ax 005f1 48 8d 7f 02 lea rdi, QWORD PTR [rdi+2] 005f5 3b 73 08 cmp esi, DWORD PTR [rbx+8] 005f8 7c ea jl SHORT $LL15@stbi__pars ; 4683 : } 005fa e9 95 01 00 00 jmp $LN8@stbi__pars $LN59@stbi__pars: ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger 005ff 85 c9 test ecx, ecx 00601 0f 8e 8d 01 00 00 jle $LN8@stbi__pars 00607 48 8d bd 70 0f 00 00 lea rdi, QWORD PTR tc$[rbp-256] 0060e 4c 8d 25 00 00 00 00 lea r12, OFFSET FLAT:stbi__depth_scale_table $LL18@stbi__pars: 00615 48 8b cb mov rcx, rbx 00618 e8 00 00 00 00 call stbi__get16be 0061d 49 63 4d 20 movsxd rcx, DWORD PTR [r13+32] 00621 48 8d 7f 01 lea rdi, QWORD PTR [rdi+1] 00625 0f b6 c0 movzx eax, al 00628 ff c6 inc esi 0062a 42 0f b6 14 21 movzx edx, BYTE PTR [rcx+r12] 0062f 0f af c2 imul eax, edx 00632 88 47 ff mov BYTE PTR [rdi-1], al 00635 3b 73 08 cmp esi, DWORD PTR [rbx+8] 00638 7c db jl SHORT $LL18@stbi__pars ; 4686 : } ; 4687 : } ; 4688 : break; 0063a 44 8b 64 24 4c mov r12d, DWORD PTR interlace$1$[rsp] 0063f e9 50 01 00 00 jmp $LN8@stbi__pars $LN44@stbi__pars: ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); 00644 83 7c 24 44 00 cmp DWORD PTR first$1$[rsp], 0 00649 0f 85 7e 08 00 00 jne $LN354@stbi__pars ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); 0064f 81 fe 00 03 00 00 cmp esi, 768 ; 00000300H 00655 0f 87 56 08 00 00 ja $LN356@stbi__pars ; 4653 : pal_len = c.length / 3; 0065b b8 ab aa aa aa mov eax, -1431655765 ; aaaaaaabH 00660 f7 e6 mul esi 00662 44 8b fa mov r15d, edx 00665 41 d1 ef shr r15d, 1 ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); 00668 43 8d 04 7f lea eax, DWORD PTR [r15+r15*2] 0066c 3b c6 cmp eax, esi 0066e 0f 85 3d 08 00 00 jne $LN356@stbi__pars ; 4655 : for (i = 0; i < pal_len; ++i) { 00674 33 c0 xor eax, eax 00676 8b f0 mov esi, eax 00678 45 85 ff test r15d, r15d 0067b 0f 84 13 01 00 00 je $LN8@stbi__pars 00681 0f 1f 40 00 66 66 66 0f 1f 84 00 00 00 00 00 npad 15 $LL9@stbi__pars: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00690 48 8b 93 c0 00 00 00 mov rdx, QWORD PTR [rbx+192] 00697 48 3b 93 c8 00 00 00 cmp rdx, QWORD PTR [rbx+200] 0069e 73 0f jae SHORT $LN109@stbi__pars ; 1078 : return *s->img_buffer++; 006a0 0f b6 0a movzx ecx, BYTE PTR [rdx] 006a3 48 ff c2 inc rdx 006a6 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx 006ad eb 27 jmp SHORT $LN108@stbi__pars $LN109@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 006af 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 006b3 74 1f je SHORT $LN110@stbi__pars ; 1080 : stbi__refill_buffer(s); 006b5 48 8b cb mov rcx, rbx 006b8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 006bd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006c4 0f b6 08 movzx ecx, BYTE PTR [rax] 006c7 48 8d 50 01 lea rdx, QWORD PTR [rax+1] 006cb 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx 006d2 eb 02 jmp SHORT $LN108@stbi__pars $LN110@stbi__pars: ; 1082 : } ; 1083 : return 0; 006d4 32 c9 xor cl, cl $LN108@stbi__pars: ; 4656 : palette[i * 4 + 0] = stbi__get8(s); 006d6 8d 3c b5 00 00 00 00 lea edi, DWORD PTR [rsi*4] 006dd 88 8c 3d 80 0f 00 00 mov BYTE PTR palette$[rbp+rdi-256], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 006e4 48 3b 93 c8 00 00 00 cmp rdx, QWORD PTR [rbx+200] 006eb 73 10 jae SHORT $LN113@stbi__pars ; 1078 : return *s->img_buffer++; 006ed 44 0f b6 02 movzx r8d, BYTE PTR [rdx] 006f1 48 ff c2 inc rdx 006f4 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx 006fb eb 29 jmp SHORT $LN112@stbi__pars $LN113@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 006fd 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00701 74 20 je SHORT $LN114@stbi__pars ; 1080 : stbi__refill_buffer(s); 00703 48 8b cb mov rcx, rbx 00706 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0070b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00712 44 0f b6 00 movzx r8d, BYTE PTR [rax] 00716 48 8d 50 01 lea rdx, QWORD PTR [rax+1] 0071a 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx 00721 eb 03 jmp SHORT $LN112@stbi__pars $LN114@stbi__pars: ; 1082 : } ; 1083 : return 0; 00723 45 32 c0 xor r8b, r8b $LN112@stbi__pars: ; 4657 : palette[i * 4 + 1] = stbi__get8(s); 00726 8d 47 01 lea eax, DWORD PTR [rdi+1] 00729 44 88 84 05 80 0f 00 00 mov BYTE PTR palette$[rbp+rax-256], r8b ; 1077 : if (s->img_buffer < s->img_buffer_end) 00731 48 3b 93 c8 00 00 00 cmp rdx, QWORD PTR [rbx+200] 00738 73 11 jae SHORT $LN117@stbi__pars ; 1078 : return *s->img_buffer++; 0073a 44 0f b6 02 movzx r8d, BYTE PTR [rdx] 0073e 48 8d 42 01 lea rax, QWORD PTR [rdx+1] 00742 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00749 eb 28 jmp SHORT $LN116@stbi__pars $LN117@stbi__pars: ; 1079 : if (s->read_from_callbacks) { 0074b 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0074f 74 1f je SHORT $LN118@stbi__pars ; 1080 : stbi__refill_buffer(s); 00751 48 8b cb mov rcx, rbx 00754 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00759 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00760 44 0f b6 00 movzx r8d, BYTE PTR [rax] 00764 48 ff c0 inc rax 00767 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0076e eb 03 jmp SHORT $LN116@stbi__pars $LN118@stbi__pars: ; 1082 : } ; 1083 : return 0; 00770 45 32 c0 xor r8b, r8b $LN116@stbi__pars: ; 4658 : palette[i * 4 + 2] = stbi__get8(s); 00773 8d 47 02 lea eax, DWORD PTR [rdi+2] 00776 ff c6 inc esi 00778 44 88 84 05 80 0f 00 00 mov BYTE PTR palette$[rbp+rax-256], r8b ; 4659 : palette[i * 4 + 3] = 255; 00780 8d 47 03 lea eax, DWORD PTR [rdi+3] 00783 c6 84 05 80 0f 00 00 ff mov BYTE PTR palette$[rbp+rax-256], 255 ; 000000ffH 0078b 41 3b f7 cmp esi, r15d 0078e 0f 82 fc fe ff ff jb $LL9@stbi__pars $LN8@stbi__pars: ; 1168 : stbi__uint32 z = stbi__get16be(s); 00794 48 8b cb mov rcx, rbx 00797 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 0079c 48 8b cb mov rcx, rbx 0079f e8 00 00 00 00 call stbi__get16be ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } 007a4 e9 fc f8 ff ff jmp $LL2@stbi__pars $LN75@stbi__pars: ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component 007a9 41 8b 45 20 mov eax, DWORD PTR [r13+32] 007ad 0f af 03 imul eax, DWORD PTR [rbx] 007b0 83 c0 07 add eax, 7 007b3 c1 e8 03 shr eax, 3 ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; 007b6 0f af 43 08 imul eax, DWORD PTR [rbx+8] 007ba ff c0 inc eax 007bc 0f af 43 04 imul eax, DWORD PTR [rbx+4] ; 4024 : char* p = (char*)stbi__malloc(initial_size); 007c0 48 63 f0 movsxd rsi, eax ; 438 : return STBI_MALLOC(size); 007c3 48 8b ce mov rcx, rsi 007c6 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 007cc 48 8b c8 mov rcx, rax ; 4025 : if (p == NULL) return NULL; 007cf 48 85 c0 test rax, rax 007d2 75 09 jne SHORT $LN193@stbi__pars 007d4 49 89 45 10 mov QWORD PTR [r13+16], rax 007d8 e9 13 07 00 00 jmp $LN327@stbi__pars $LN193@stbi__pars: ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; 007dd 48 63 44 24 48 movsxd rax, DWORD PTR ioff$1$[rsp] ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 007e2 44 8b 7c 24 50 mov r15d, DWORD PTR is_iphone$1$[rsp] ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; 007e7 48 03 c7 add rax, rdi 007ea 48 89 44 24 78 mov QWORD PTR a$15[rsp+8], rax ; 3993 : a->zout_end = obuf + olen; 007ef 48 8d 04 0e lea rax, QWORD PTR [rsi+rcx] ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 007f3 33 f6 xor esi, esi ; 3991 : a->zout_start = obuf; 007f5 48 89 4d 90 mov QWORD PTR a$15[rbp-224], rcx ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 007f9 8b d6 mov edx, esi ; 3992 : a->zout = obuf; 007fb 48 89 4d 88 mov QWORD PTR a$15[rbp-232], rcx ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 007ff 45 85 ff test r15d, r15d ; 4026 : a.zbuffer = (stbi_uc*)buffer; 00802 48 89 7c 24 70 mov QWORD PTR a$15[rsp], rdi ; 3996 : return stbi__parse_zlib(a, parse_header); 00807 48 8d 4c 24 70 lea rcx, QWORD PTR a$15[rsp] 0080c 48 89 45 98 mov QWORD PTR a$15[rbp-216], rax ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 00810 0f 94 c2 sete dl ; 3994 : a->z_expandable = exp; 00813 c7 45 a0 01 00 00 00 mov DWORD PTR a$15[rbp-208], 1 ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); 0081a e8 00 00 00 00 call stbi__parse_zlib ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { 0081f 85 c0 test eax, eax 00821 0f 84 4a 04 00 00 je $LN194@stbi__pars ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; 00827 48 8b 45 90 mov rax, QWORD PTR a$15[rbp-224] 0082b 8b 7d 88 mov edi, DWORD PTR a$15[rbp-232] 0082e 2b 7d 90 sub edi, DWORD PTR a$15[rbp-224] ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); 00831 49 89 45 10 mov QWORD PTR [r13+16], rax ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error 00835 48 85 c0 test rax, rax 00838 0f 84 b2 06 00 00 je $LN327@stbi__pars ; 4727 : STBI_FREE(z->idata); z->idata = NULL; 0083e 49 8b 4d 08 mov rcx, QWORD PTR [r13+8] 00842 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) 00848 8b 4c 24 58 mov ecx, DWORD PTR req_comp$1$[rsp] 0084c 49 89 75 08 mov QWORD PTR [r13+8], rsi 00850 8b 43 08 mov eax, DWORD PTR [rbx+8] 00853 0f b6 74 24 40 movzx esi, BYTE PTR pal_img_n$1$[rsp] 00858 44 8d 48 01 lea r9d, DWORD PTR [rax+1] 0085c 41 3b c9 cmp ecx, r9d 0085f 75 0e jne SHORT $LN80@stbi__pars 00861 83 f9 03 cmp ecx, 3 00864 74 09 je SHORT $LN80@stbi__pars 00866 40 84 f6 test sil, sil 00869 0f 84 a2 00 00 00 je $LN508@stbi__pars $LN80@stbi__pars: 0086f 44 0f b6 74 24 41 movzx r14d, BYTE PTR has_trans$1$[rsp] 00875 45 84 f6 test r14b, r14b 00878 75 03 jne SHORT $LN78@stbi__pars ; 4730 : else ; 4731 : s->img_out_n = s->img_n; 0087a 44 8b c8 mov r9d, eax $LN78@stbi__pars: ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; 0087d 8b 44 24 54 mov eax, DWORD PTR color$1$[rsp] 00881 44 8b c7 mov r8d, edi 00884 44 89 4b 0c mov DWORD PTR [rbx+12], r9d 00888 49 8b cd mov rcx, r13 0088b 49 8b 55 10 mov rdx, QWORD PTR [r13+16] 0088f 44 89 64 24 30 mov DWORD PTR [rsp+48], r12d 00894 89 44 24 28 mov DWORD PTR [rsp+40], eax 00898 41 8b 45 20 mov eax, DWORD PTR [r13+32] 0089c 89 44 24 20 mov DWORD PTR [rsp+32], eax 008a0 e8 00 00 00 00 call stbi__create_png_image 008a5 85 c0 test eax, eax 008a7 0f 84 43 06 00 00 je $LN327@stbi__pars ; 4733 : if (has_trans) { 008ad 45 84 f6 test r14b, r14b 008b0 0f 84 0a 01 00 00 je $LN278@stbi__pars ; 4734 : if (z->depth == 16) { 008b6 49 8b 4d 00 mov rcx, QWORD PTR [r13] 008ba 8b 41 04 mov eax, DWORD PTR [rcx+4] 008bd 0f af 01 imul eax, DWORD PTR [rcx] 008c0 41 83 7d 20 10 cmp DWORD PTR [r13+32], 16 008c5 49 8b 4d 18 mov rcx, QWORD PTR [r13+24] 008c9 0f 85 88 00 00 00 jne $LN83@stbi__pars ; 4454 : for (i = 0; i < pixel_count; ++i) { 008cf 85 c0 test eax, eax 008d1 0f 84 e9 00 00 00 je $LN278@stbi__pars ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { 008d7 45 33 d2 xor r10d, r10d 008da 83 7b 0c 02 cmp DWORD PTR [rbx+12], 2 008de 75 3c jne SHORT $LN269@stbi__pars 008e0 44 0f b7 85 74 0f 00 00 movzx r8d, WORD PTR tc16$[rbp-256] 008e8 8b d0 mov edx, eax 008ea 66 0f 1f 44 00 00 npad 6 $LL265@stbi__pars: ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); 008f0 66 44 39 01 cmp WORD PTR [rcx], r8w ; 4456 : p += 2; 008f4 48 8d 49 04 lea rcx, QWORD PTR [rcx+4] 008f8 b8 ff ff 00 00 mov eax, 65535 ; 0000ffffH 008fd 66 41 0f 44 c2 cmove ax, r10w 00902 66 89 41 fe mov WORD PTR [rcx-2], ax 00906 48 83 ea 01 sub rdx, 1 0090a 75 e4 jne SHORT $LL265@stbi__pars ; 4457 : } ; 4458 : } 0090c e9 af 00 00 00 jmp $LN278@stbi__pars $LN508@stbi__pars: ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) 00911 44 0f b6 74 24 41 movzx r14d, BYTE PTR has_trans$1$[rsp] ; 4729 : s->img_out_n = s->img_n + 1; 00917 e9 61 ff ff ff jmp $LN78@stbi__pars $LN269@stbi__pars: 0091c 0f b7 95 78 0f 00 00 movzx edx, WORD PTR tc16$[rbp-252] 00923 44 0f b7 85 76 0f 00 00 movzx r8d, WORD PTR tc16$[rbp-254] 0092b 44 0f b7 8d 74 0f 00 00 movzx r9d, WORD PTR tc16$[rbp-256] $LL268@stbi__pars: ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) 00933 66 44 39 09 cmp WORD PTR [rcx], r9w 00937 75 12 jne SHORT $LN271@stbi__pars 00939 66 44 39 41 02 cmp WORD PTR [rcx+2], r8w 0093e 75 0b jne SHORT $LN271@stbi__pars 00940 66 39 51 04 cmp WORD PTR [rcx+4], dx 00944 75 05 jne SHORT $LN271@stbi__pars ; 4462 : p[3] = 0; 00946 66 44 89 51 06 mov WORD PTR [rcx+6], r10w $LN271@stbi__pars: ; 4463 : p += 4; 0094b 48 83 c1 08 add rcx, 8 0094f 48 83 e8 01 sub rax, 1 00953 75 de jne SHORT $LL268@stbi__pars ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } 00955 eb 69 jmp SHORT $LN278@stbi__pars $LN83@stbi__pars: ; 4428 : for (i = 0; i < pixel_count; ++i) { 00957 85 c0 test eax, eax 00959 74 65 je SHORT $LN278@stbi__pars ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { 0095b 83 7b 0c 02 cmp DWORD PTR [rbx+12], 2 0095f 75 2a jne SHORT $LN280@stbi__pars 00961 44 0f b6 85 70 0f 00 00 movzx r8d, BYTE PTR tc$[rbp-256] 00969 45 33 d2 xor r10d, r10d 0096c 8b d0 mov edx, eax 0096e 66 90 npad 2 $LL276@stbi__pars: ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); 00970 44 38 01 cmp BYTE PTR [rcx], r8b ; 4430 : p += 2; 00973 48 8d 49 02 lea rcx, QWORD PTR [rcx+2] 00977 b8 ff 00 00 00 mov eax, 255 ; 000000ffH 0097c 41 0f 44 c2 cmove eax, r10d 00980 88 41 ff mov BYTE PTR [rcx-1], al 00983 48 83 ea 01 sub rdx, 1 00987 75 e7 jne SHORT $LL276@stbi__pars ; 4431 : } ; 4432 : } 00989 eb 35 jmp SHORT $LN278@stbi__pars $LN280@stbi__pars: 0098b 0f b6 95 72 0f 00 00 movzx edx, BYTE PTR tc$[rbp-254] 00992 44 0f b6 85 71 0f 00 00 movzx r8d, BYTE PTR tc$[rbp-255] 0099a 44 0f b6 8d 70 0f 00 00 movzx r9d, BYTE PTR tc$[rbp-256] $LL279@stbi__pars: ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) 009a2 44 38 09 cmp BYTE PTR [rcx], r9b 009a5 75 0f jne SHORT $LN282@stbi__pars 009a7 44 38 41 01 cmp BYTE PTR [rcx+1], r8b 009ab 75 09 jne SHORT $LN282@stbi__pars 009ad 38 51 02 cmp BYTE PTR [rcx+2], dl 009b0 75 04 jne SHORT $LN282@stbi__pars ; 4436 : p[3] = 0; 009b2 c6 41 03 00 mov BYTE PTR [rcx+3], 0 $LN282@stbi__pars: ; 4437 : p += 4; 009b6 48 83 c1 04 add rcx, 4 009ba 48 83 e8 01 sub rax, 1 009be 75 e2 jne SHORT $LL279@stbi__pars $LN278@stbi__pars: ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) 009c0 44 8b 25 00 00 00 00 mov r12d, DWORD PTR _tls_index 009c7 45 85 ff test r15d, r15d 009ca 0f 84 3a 01 00 00 je $LN292@stbi__pars 009d0 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 009d9 4a 8b 14 e0 mov rdx, QWORD PTR [rax+r12*8] 009dd b8 00 00 00 00 mov eax, OFFSET FLAT:stbi__de_iphone_flag_set 009e2 83 3c 10 00 cmp DWORD PTR [rax+rdx], 0 009e6 74 0a je SHORT $LN97@stbi__pars 009e8 b8 00 00 00 00 mov eax, OFFSET FLAT:stbi__de_iphone_flag_local 009ed 8b 04 10 mov eax, DWORD PTR [rax+rdx] 009f0 eb 06 jmp SHORT $LN98@stbi__pars $LN97@stbi__pars: 009f2 8b 05 00 00 00 00 mov eax, DWORD PTR stbi__de_iphone_flag_global $LN98@stbi__pars: 009f8 85 c0 test eax, eax 009fa 0f 84 0a 01 00 00 je $LN292@stbi__pars 00a00 83 7b 0c 02 cmp DWORD PTR [rbx+12], 2 00a04 0f 8e 00 01 00 00 jle $LN292@stbi__pars ; 4549 : stbi__context* s = z->s; 00a0a 49 8b 45 00 mov rax, QWORD PTR [r13] ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; 00a0e 4d 8b 55 18 mov r10, QWORD PTR [r13+24] 00a12 8b 48 04 mov ecx, DWORD PTR [rax+4] 00a15 0f af 08 imul ecx, DWORD PTR [rax] ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb 00a18 83 78 0c 03 cmp DWORD PTR [rax+12], 3 00a1c 75 31 jne SHORT $LN294@stbi__pars ; 4554 : for (i = 0; i < pixel_count; ++i) { 00a1e 85 c9 test ecx, ecx 00a20 0f 84 e4 00 00 00 je $LN292@stbi__pars 00a26 8b d1 mov edx, ecx 00a28 0f 1f 84 00 00 00 00 00 npad 8 $LL287@stbi__pars: ; 4555 : stbi_uc t = p[0]; 00a30 41 0f b6 0a movzx ecx, BYTE PTR [r10] ; 4556 : p[0] = p[2]; 00a34 41 0f b6 42 02 movzx eax, BYTE PTR [r10+2] 00a39 41 88 02 mov BYTE PTR [r10], al ; 4557 : p[2] = t; 00a3c 41 88 4a 02 mov BYTE PTR [r10+2], cl ; 4558 : p += 3; 00a40 4d 8d 52 03 lea r10, QWORD PTR [r10+3] 00a44 48 83 ea 01 sub rdx, 1 00a48 75 e6 jne SHORT $LL287@stbi__pars ; 4559 : } ; 4560 : } 00a4a e9 bb 00 00 00 jmp $LN292@stbi__pars $LN294@stbi__pars: ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { 00a4f b8 00 00 00 00 mov eax, OFFSET FLAT:stbi__unpremultiply_on_load_set 00a54 83 3c 10 00 cmp DWORD PTR [rax+rdx], 0 00a58 74 0a je SHORT $LN301@stbi__pars 00a5a b8 00 00 00 00 mov eax, OFFSET FLAT:stbi__unpremultiply_on_load_local 00a5f 8b 04 10 mov eax, DWORD PTR [rax+rdx] 00a62 eb 06 jmp SHORT $LN302@stbi__pars $LN301@stbi__pars: 00a64 8b 05 00 00 00 00 mov eax, DWORD PTR stbi__unpremultiply_on_load_global $LN302@stbi__pars: ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { 00a6a 85 c9 test ecx, ecx 00a6c 0f 84 98 00 00 00 je $LN292@stbi__pars ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { 00a72 85 c0 test eax, eax 00a74 74 74 je SHORT $LN296@stbi__pars ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { 00a76 8b f9 mov edi, ecx 00a78 0f 1f 84 00 00 00 00 00 npad 8 $LL290@stbi__pars: ; 4566 : stbi_uc a = p[3]; 00a80 41 0f b6 42 03 movzx eax, BYTE PTR [r10+3] ; 4567 : stbi_uc t = p[0]; 00a85 45 0f b6 1a movzx r11d, BYTE PTR [r10] 00a89 41 0f b6 4a 02 movzx ecx, BYTE PTR [r10+2] ; 4568 : if (a) { 00a8e 84 c0 test al, al 00a90 74 42 je SHORT $LN298@stbi__pars ; 4569 : stbi_uc half = a / 2; 00a92 44 8b c0 mov r8d, eax 00a95 44 8b c8 mov r9d, eax ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; 00a98 41 0f b6 42 01 movzx eax, BYTE PTR [r10+1] 00a9d 33 d2 xor edx, edx 00a9f 69 c0 ff 00 00 00 imul eax, eax, 255 ; 000000ffH 00aa5 41 d1 e8 shr r8d, 1 00aa8 41 03 c0 add eax, r8d 00aab 41 f7 f1 div r9d ; 4572 : p[2] = (t * 255 + half) / a; 00aae 33 d2 xor edx, edx 00ab0 41 88 42 01 mov BYTE PTR [r10+1], al 00ab4 41 69 c3 ff 00 00 00 imul eax, r11d, 255 ; 000000ffH 00abb 41 03 c0 add eax, r8d 00abe 41 f7 f1 div r9d 00ac1 33 d2 xor edx, edx 00ac3 44 8b d8 mov r11d, eax 00ac6 69 c1 ff 00 00 00 imul eax, ecx, 255 ; 000000ffH 00acc 41 03 c0 add eax, r8d 00acf 41 f7 f1 div r9d ; 4573 : } 00ad2 eb 03 jmp SHORT $LN299@stbi__pars $LN298@stbi__pars: ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; 00ad4 0f b6 c1 movzx eax, cl $LN299@stbi__pars: ; 4577 : } ; 4578 : p += 4; 00ad7 41 88 02 mov BYTE PTR [r10], al 00ada 45 88 5a 02 mov BYTE PTR [r10+2], r11b 00ade 49 83 c2 04 add r10, 4 00ae2 48 83 ef 01 sub rdi, 1 00ae6 75 98 jne SHORT $LL290@stbi__pars ; 4579 : } ; 4580 : } 00ae8 eb 20 jmp SHORT $LN292@stbi__pars $LN296@stbi__pars: ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { 00aea 8b d1 mov edx, ecx 00aec 0f 1f 40 00 npad 4 $LL293@stbi__pars: ; 4584 : stbi_uc t = p[0]; 00af0 41 0f b6 0a movzx ecx, BYTE PTR [r10] ; 4585 : p[0] = p[2]; 00af4 41 0f b6 42 02 movzx eax, BYTE PTR [r10+2] 00af9 41 88 02 mov BYTE PTR [r10], al ; 4586 : p[2] = t; 00afc 41 88 4a 02 mov BYTE PTR [r10+2], cl ; 4587 : p += 4; 00b00 4d 8d 52 04 lea r10, QWORD PTR [r10+4] 00b04 48 83 ea 01 sub rdx, 1 00b08 75 e6 jne SHORT $LL293@stbi__pars $LN292@stbi__pars: ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { 00b0a 40 84 f6 test sil, sil 00b0d 0f 84 2c 01 00 00 je $LN88@stbi__pars ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; 00b13 8b 44 24 58 mov eax, DWORD PTR req_comp$1$[rsp] 00b17 40 0f b6 f6 movzx esi, sil 00b1b 89 73 08 mov DWORD PTR [rbx+8], esi 00b1e 89 73 0c mov DWORD PTR [rbx+12], esi 00b21 83 f8 03 cmp eax, 3 00b24 7c 05 jl SHORT $LN90@stbi__pars 00b26 89 43 0c mov DWORD PTR [rbx+12], eax 00b29 8b f0 mov esi, eax $LN90@stbi__pars: ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; 00b2b 49 8b 45 00 mov rax, QWORD PTR [r13] ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; 00b2f 49 8b 7d 18 mov rdi, QWORD PTR [r13+24] 00b33 44 8b 70 04 mov r14d, DWORD PTR [rax+4] 00b37 44 0f af 30 imul r14d, DWORD PTR [rax] ; 467 : if (a < 0 || b < 0) return 0; 00b3b 45 85 f6 test r14d, r14d 00b3e 0f 88 e2 00 00 00 js $LN463@stbi__pars 00b44 85 f6 test esi, esi 00b46 0f 88 da 00 00 00 js $LN463@stbi__pars ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00b4c 74 11 je SHORT $LN244@stbi__pars ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00b4e b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00b53 99 cdq 00b54 f7 fe idiv esi ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 00b56 44 3b f0 cmp r14d, eax 00b59 0f 8f c7 00 00 00 jg $LN463@stbi__pars $LN244@stbi__pars: ; 502 : return stbi__malloc(a * b + add); 00b5f 8b c6 mov eax, esi 00b61 41 0f af c6 imul eax, r14d 00b65 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 00b68 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00b6e 4c 8b f8 mov r15, rax ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); 00b71 48 85 c0 test rax, rax 00b74 0f 84 ac 00 00 00 je $LN463@stbi__pars ; 4481 : for (i = 0; i < pixel_count; ++i) { 00b7a 45 85 f6 test r14d, r14d 00b7d 0f 84 93 00 00 00 je $LN237@stbi__pars ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { 00b83 45 8b ce mov r9d, r14d 00b86 4c 8d 40 02 lea r8, QWORD PTR [rax+2] 00b8a 83 fe 03 cmp esi, 3 00b8d 75 46 jne SHORT $LL238@stbi__pars 00b8f 90 npad 1 $LL235@stbi__pars: ; 4482 : int n = orig[i] * 4; 00b90 0f b6 17 movzx edx, BYTE PTR [rdi] ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; 00b93 4d 8d 40 03 lea r8, QWORD PTR [r8+3] 00b97 48 8d 7f 01 lea rdi, QWORD PTR [rdi+1] 00b9b 0f b6 84 95 80 0f 00 00 movzx eax, BYTE PTR palette$[rbp+rdx*4-256] 00ba3 0f b6 8c 95 82 0f 00 00 movzx ecx, BYTE PTR palette$[rbp+rdx*4-254] 00bab 41 88 40 fb mov BYTE PTR [r8-5], al 00baf 0f b6 84 95 81 0f 00 00 movzx eax, BYTE PTR palette$[rbp+rdx*4-255] 00bb7 41 88 40 fc mov BYTE PTR [r8-4], al 00bbb 41 88 48 fd mov BYTE PTR [r8-3], cl 00bbf 49 83 e9 01 sub r9, 1 00bc3 75 cb jne SHORT $LL235@stbi__pars ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); 00bc5 49 8b 4d 18 mov rcx, QWORD PTR [r13+24] 00bc9 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4500 : a->out = temp_out; 00bcf 4d 89 7d 18 mov QWORD PTR [r13+24], r15 ; 4710 : z->idata = p; 00bd3 eb 72 jmp SHORT $LN92@stbi__pars $LL238@stbi__pars: ; 4491 : int n = orig[i] * 4; 00bd5 0f b6 17 movzx edx, BYTE PTR [rdi] ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; 00bd8 4d 8d 40 04 lea r8, QWORD PTR [r8+4] 00bdc 48 8d 7f 01 lea rdi, QWORD PTR [rdi+1] 00be0 0f b6 84 95 80 0f 00 00 movzx eax, BYTE PTR palette$[rbp+rdx*4-256] 00be8 0f b6 8c 95 83 0f 00 00 movzx ecx, BYTE PTR palette$[rbp+rdx*4-253] 00bf0 41 88 40 fa mov BYTE PTR [r8-6], al 00bf4 0f b6 84 95 81 0f 00 00 movzx eax, BYTE PTR palette$[rbp+rdx*4-255] 00bfc 41 88 40 fb mov BYTE PTR [r8-5], al 00c00 0f b6 84 95 82 0f 00 00 movzx eax, BYTE PTR palette$[rbp+rdx*4-254] 00c08 41 88 40 fc mov BYTE PTR [r8-4], al 00c0c 41 88 48 fd mov BYTE PTR [r8-3], cl 00c10 49 83 e9 01 sub r9, 1 00c14 75 bf jne SHORT $LL238@stbi__pars $LN237@stbi__pars: ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); 00c16 49 8b 4d 18 mov rcx, QWORD PTR [r13+24] 00c1a ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4500 : a->out = temp_out; 00c20 4d 89 7d 18 mov QWORD PTR [r13+24], r15 ; 4710 : z->idata = p; 00c24 eb 21 jmp SHORT $LN92@stbi__pars $LN463@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00c26 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00c2f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00c36 4a 8b 04 e0 mov rax, QWORD PTR [rax+r12*8] ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); 00c3a e9 a8 02 00 00 jmp $LN635@stbi__pars $LN88@stbi__pars: ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { 00c3f 45 84 f6 test r14b, r14b 00c42 74 03 je SHORT $LN92@stbi__pars ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; 00c44 ff 43 08 inc DWORD PTR [rbx+8] $LN92@stbi__pars: ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; 00c47 49 8b 4d 10 mov rcx, QWORD PTR [r13+16] 00c4b ff 15 00 00 00 00 call QWORD PTR __imp_free 00c51 33 c0 xor eax, eax ; 1168 : stbi__uint32 z = stbi__get16be(s); 00c53 48 8b cb mov rcx, rbx ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; 00c56 49 89 45 10 mov QWORD PTR [r13+16], rax ; 1168 : stbi__uint32 z = stbi__get16be(s); 00c5a e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00c5f 48 8b cb mov rcx, rbx 00c62 e8 00 00 00 00 call stbi__get16be ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; 00c67 b8 01 00 00 00 mov eax, 1 00c6c e9 81 02 00 00 jmp $LN3@stbi__pars $LN194@stbi__pars: ; 4033 : STBI_FREE(a.zout_start); 00c71 48 8b 4d 90 mov rcx, QWORD PTR a$15[rbp-224] 00c75 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4034 : return NULL; 00c7b 49 89 75 10 mov QWORD PTR [r13+16], rsi ; 4710 : z->idata = p; 00c7f e9 6c 02 00 00 jmp $LN327@stbi__pars $LN324@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00c84 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00c8a 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00c93 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00c97 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07CKIELOEH@no?5PLTE@ ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); 00c9e e9 44 02 00 00 jmp $LN635@stbi__pars $LN328@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00ca3 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00ca9 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00cb2 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00cb6 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); 00cbd e9 25 02 00 00 jmp $LN635@stbi__pars $LN329@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00cc2 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00cc8 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00cd1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00cd5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09MNNCNKEO@outofdata@ ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); 00cdc e9 06 02 00 00 jmp $LN635@stbi__pars $LN326@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00ce1 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00ce7 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00cf0 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00cf4 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@PLHGLONG@IDAT?5size?5limit@ ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); 00cfb e9 e7 01 00 00 jmp $LN635@stbi__pars $LN336@stbi__pars: ; 4781 : } 00d00 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d06 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d0f 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d13 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09MBBNGCKB@bad?5ctype@ 00d1a e9 c8 01 00 00 jmp $LN635@stbi__pars $LN338@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00d1f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d25 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d2e 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d32 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MDMBDDFG@bad?5comp?5method@ ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); 00d39 e9 a9 01 00 00 jmp $LN635@stbi__pars $LN339@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00d3e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d44 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d4d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d51 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BC@GHLIKKMD@bad?5filter?5method@ ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); 00d58 e9 8a 01 00 00 jmp $LN635@stbi__pars $LN39@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00d5d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d63 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d6c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d70 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@FNFBHCOO@0?9pixel?5image@ ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); 00d77 e9 6b 01 00 00 jmp $LN635@stbi__pars $LN340@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00d7c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00d82 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00d8b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00d8f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BF@JCGDPBAA@bad?5interlace?5method@ ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); 00d96 e9 4c 01 00 00 jmp $LN635@stbi__pars $LN334@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00d9b 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00da1 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00daa 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00dae 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BE@EJHIPKNO@1?12?14?18?116?9bit?5only@ ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); 00db5 e9 2d 01 00 00 jmp $LN635@stbi__pars $LN331@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00dba 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00dc0 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00dc9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00dcd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@POJLKMKK@bad?5IHDR?5len@ ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); 00dd4 e9 0e 01 00 00 jmp $LN635@stbi__pars $LN330@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00dd9 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00ddf 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00de8 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00dec 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@KBHBNJOK@multiple?5IHDR@ ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); 00df3 e9 ef 00 00 00 jmp $LN635@stbi__pars $LN345@stbi__pars: ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); 00df8 8b c2 mov eax, edx ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); 00dfa 88 15 03 00 00 00 mov BYTE PTR ?invalid_chunk@?BP@??stbi__parse_png_file@@9@9+3, dl 00e00 c1 e8 18 shr eax, 24 00e03 88 05 00 00 00 00 mov BYTE PTR ?invalid_chunk@?BP@??stbi__parse_png_file@@9@9, al 00e09 8b c2 mov eax, edx 00e0b c1 e8 10 shr eax, 16 00e0e 88 05 01 00 00 00 mov BYTE PTR ?invalid_chunk@?BP@??stbi__parse_png_file@@9@9+1, al 00e14 8b c2 mov eax, edx ; 431 : stbi__g_failure_reason = str; 00e16 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); 00e1c c1 e8 08 shr eax, 8 00e1f 88 05 02 00 00 00 mov BYTE PTR ?invalid_chunk@?BP@??stbi__parse_png_file@@9@9+2, al ; 431 : stbi__g_failure_reason = str; 00e25 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00e2e 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00e32 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:?invalid_chunk@?BP@??stbi__parse_png_file@@9@9 ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); 00e39 e9 a9 00 00 00 jmp $LN635@stbi__pars $LN350@stbi__pars: ; 4781 : } 00e3e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00e44 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00e4d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00e51 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@KDLCCKCH@bad?5tRNS?5len@ 00e58 e9 8a 00 00 00 jmp $LN635@stbi__pars $LN349@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00e5d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00e63 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00e6c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00e70 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BB@CEDNNLBG@tRNS?5before?5PLTE@ ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); 00e77 eb 6e jmp SHORT $LN635@stbi__pars $LN351@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00e79 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00e7f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00e88 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00e8c 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@ENDPGCHB@tRNS?5with?5alpha@ ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); 00e93 eb 52 jmp SHORT $LN635@stbi__pars $LN347@stbi__pars: ; 431 : stbi__g_failure_reason = str; 00e95 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00e9b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00ea4 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00ea8 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@PCPJHDKJ@tRNS?5after?5IDAT@ ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); 00eaf eb 36 jmp SHORT $LN635@stbi__pars $LN356@stbi__pars: ; 4781 : } 00eb1 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00eb7 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00ec0 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00ec4 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@JCPAJAKB@invalid?5PLTE@ 00ecb eb 1a jmp SHORT $LN635@stbi__pars $LN354@stbi__pars: 00ecd 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00ed3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00edc 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00ee0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@JEAFOMAF@first?5not?5IHDR@ $LN635@stbi__pars: 00ee7 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00eec 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN327@stbi__pars: 00ef0 33 c0 xor eax, eax $LN3@stbi__pars: 00ef2 48 8b 8d 80 13 00 00 mov rcx, QWORD PTR __$ArrayPad$[rbp-256] 00ef9 48 33 cc xor rcx, rsp 00efc e8 00 00 00 00 call __security_check_cookie 00f01 4c 8d 9c 24 90 14 00 00 lea r11, QWORD PTR [rsp+5264] 00f09 49 8b 5b 38 mov rbx, QWORD PTR [r11+56] 00f0d 49 8b 73 40 mov rsi, QWORD PTR [r11+64] 00f11 49 8b 7b 48 mov rdi, QWORD PTR [r11+72] 00f15 49 8b e3 mov rsp, r11 00f18 41 5f pop r15 00f1a 41 5e pop r14 00f1c 41 5d pop r13 00f1e 41 5c pop r12 00f20 5d pop rbp 00f21 c3 ret 0 stbi__parse_png_file ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__do_png _TEXT SEGMENT p$ = 80 x$ = 88 y$ = 96 n$ = 104 req_comp$ = 112 ri$ = 120 stbi__do_png PROC ; COMDAT ; 4784 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 30 sub rsp, 48 ; 00000030H ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); 0001e 8b 7c 24 70 mov edi, DWORD PTR req_comp$[rsp] 00022 45 33 e4 xor r12d, r12d 00025 4d 8b f1 mov r14, r9 00028 4d 8b f8 mov r15, r8 0002b 48 8b ea mov rbp, rdx 0002e 48 8b d9 mov rbx, rcx 00031 41 8b f4 mov esi, r12d 00034 83 ff 04 cmp edi, 4 00037 0f 87 e0 00 00 00 ja $LN3@stbi__do_p ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { 0003d 44 8b c7 mov r8d, edi 00040 33 d2 xor edx, edx 00042 e8 00 00 00 00 call stbi__parse_png_file 00047 85 c0 test eax, eax 00049 0f 84 83 00 00 00 je $LN13@stbi__do_p ; 4788 : if (p->depth <= 8) 0004f 8b 43 20 mov eax, DWORD PTR [rbx+32] 00052 83 f8 08 cmp eax, 8 00055 7f 07 jg SHORT $LN5@stbi__do_p ; 4789 : ri->bits_per_channel = 8; 00057 41 8d 44 24 08 lea eax, QWORD PTR [r12+8] 0005c eb 09 jmp SHORT $LN8@stbi__do_p $LN5@stbi__do_p: ; 4790 : else if (p->depth == 16) 0005e 83 f8 10 cmp eax, 16 00061 0f 85 9a 00 00 00 jne $LN7@stbi__do_p $LN8@stbi__do_p: ; 4794 : result = p->out; 00067 48 8b 4c 24 78 mov rcx, QWORD PTR ri$[rsp] 0006c 89 01 mov DWORD PTR [rcx], eax 0006e 48 8b 73 18 mov rsi, QWORD PTR [rbx+24] ; 4795 : p->out = NULL; 00072 4c 89 63 18 mov QWORD PTR [rbx+24], r12 ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { 00076 85 ff test edi, edi 00078 74 3f je SHORT $LN12@stbi__do_p 0007a 4c 8b 0b mov r9, QWORD PTR [rbx] 0007d 41 8b 51 0c mov edx, DWORD PTR [r9+12] 00081 3b fa cmp edi, edx 00083 74 34 je SHORT $LN12@stbi__do_p ; 4797 : if (ri->bits_per_channel == 8) 00085 41 8b 41 04 mov eax, DWORD PTR [r9+4] 00089 44 8b c7 mov r8d, edi 0008c 83 39 08 cmp DWORD PTR [rcx], 8 0008f 48 8b ce mov rcx, rsi 00092 45 8b 09 mov r9d, DWORD PTR [r9] 00095 89 44 24 20 mov DWORD PTR [rsp+32], eax 00099 75 07 jne SHORT $LN10@stbi__do_p ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 0009b e8 00 00 00 00 call stbi__convert_format 000a0 eb 05 jmp SHORT $LN28@stbi__do_p $LN10@stbi__do_p: ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 000a2 e8 00 00 00 00 call stbi__convert_format16 $LN28@stbi__do_p: ; 4801 : p->s->img_out_n = req_comp; 000a7 48 8b f0 mov rsi, rax 000aa 48 8b 03 mov rax, QWORD PTR [rbx] 000ad 89 78 0c mov DWORD PTR [rax+12], edi ; 4802 : if (result == NULL) return result; 000b0 48 85 f6 test rsi, rsi 000b3 0f 84 87 00 00 00 je $LN29@stbi__do_p $LN12@stbi__do_p: ; 4803 : } ; 4804 : *x = p->s->img_x; 000b9 48 8b 0b mov rcx, QWORD PTR [rbx] 000bc 8b 01 mov eax, DWORD PTR [rcx] 000be 89 45 00 mov DWORD PTR [rbp], eax ; 4805 : *y = p->s->img_y; 000c1 8b 41 04 mov eax, DWORD PTR [rcx+4] 000c4 41 89 07 mov DWORD PTR [r15], eax ; 4806 : if (n) *n = p->s->img_n; 000c7 4d 85 f6 test r14, r14 000ca 74 06 je SHORT $LN13@stbi__do_p 000cc 8b 41 08 mov eax, DWORD PTR [rcx+8] 000cf 41 89 06 mov DWORD PTR [r14], eax $LN13@stbi__do_p: ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; 000d2 48 8b 4b 18 mov rcx, QWORD PTR [rbx+24] 000d6 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; 000dc 48 8b 4b 10 mov rcx, QWORD PTR [rbx+16] 000e0 4c 89 63 18 mov QWORD PTR [rbx+24], r12 000e4 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4810 : STBI_FREE(p->idata); p->idata = NULL; 000ea 48 8b 4b 08 mov rcx, QWORD PTR [rbx+8] 000ee 4c 89 63 10 mov QWORD PTR [rbx+16], r12 000f2 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4811 : ; 4812 : return result; 000f8 48 8b c6 mov rax, rsi 000fb 4c 89 63 08 mov QWORD PTR [rbx+8], r12 000ff eb 41 jmp SHORT $LN1@stbi__do_p $LN7@stbi__do_p: ; 431 : stbi__g_failure_reason = str; 00101 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00107 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00110 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00114 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); 0011b eb 1a jmp SHORT $LN30@stbi__do_p $LN3@stbi__do_p: ; 431 : stbi__g_failure_reason = str; 0011d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00123 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0012c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00130 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@KBPNPPBJ@bad?5req_comp@ $LN30@stbi__do_p: ; 4813 : } 00137 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0013c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN29@stbi__do_p: 00140 33 c0 xor eax, eax $LN1@stbi__do_p: 00142 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 00147 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 0014c 48 8b 74 24 60 mov rsi, QWORD PTR [rsp+96] 00151 48 8b 7c 24 68 mov rdi, QWORD PTR [rsp+104] 00156 48 83 c4 30 add rsp, 48 ; 00000030H 0015a 41 5f pop r15 0015c 41 5e pop r14 0015e 41 5c pop r12 00160 c3 ret 0 stbi__do_png ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__png_load _TEXT SEGMENT p$ = 48 __$ArrayPad$ = 88 s$ = 160 x$ = 168 y$ = 176 comp$ = 184 req_comp$ = 192 ri$ = 200 stbi__png_load PROC ; COMDAT ; 4816 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 56 push r14 00007 41 57 push r15 00009 48 83 ec 68 sub rsp, 104 ; 00000068H 0000d 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00014 48 33 c4 xor rax, rsp 00017 48 89 44 24 58 mov QWORD PTR __$ArrayPad$[rsp], rax 0001c 8b 9c 24 c0 00 00 00 mov ebx, DWORD PTR req_comp$[rsp] ; 4785 : void* result = NULL; 00023 33 ff xor edi, edi ; 4816 : { 00025 4c 8b b4 24 c8 00 00 00 mov r14, QWORD PTR ri$[rsp] 0002d 49 8b f1 mov rsi, r9 ; 4817 : stbi__png p; ; 4818 : p.s = s; 00030 48 89 4c 24 30 mov QWORD PTR p$[rsp], rcx 00035 49 8b e8 mov rbp, r8 00038 4c 8b fa mov r15, rdx ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); 0003b 83 fb 04 cmp ebx, 4 0003e 0f 87 fc 00 00 00 ja $LN5@stbi__png_ ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { 00044 44 8b c3 mov r8d, ebx 00047 48 8d 4c 24 30 lea rcx, QWORD PTR p$[rsp] 0004c 33 d2 xor edx, edx 0004e e8 00 00 00 00 call stbi__parse_png_file 00053 85 c0 test eax, eax 00055 0f 84 87 00 00 00 je $LN23@stbi__png_ ; 4788 : if (p->depth <= 8) 0005b 8b 44 24 50 mov eax, DWORD PTR p$[rsp+32] 0005f 83 f8 08 cmp eax, 8 00062 7f 05 jg SHORT $LN7@stbi__png_ ; 4789 : ri->bits_per_channel = 8; 00064 8d 47 08 lea eax, QWORD PTR [rdi+8] 00067 eb 09 jmp SHORT $LN10@stbi__png_ $LN7@stbi__png_: ; 4790 : else if (p->depth == 16) 00069 83 f8 10 cmp eax, 16 0006c 0f 85 a8 00 00 00 jne $LN9@stbi__png_ $LN10@stbi__png_: ; 4794 : result = p->out; 00072 41 89 06 mov DWORD PTR [r14], eax 00075 48 8b 7c 24 48 mov rdi, QWORD PTR p$[rsp+24] ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { 0007a 48 8b 4c 24 30 mov rcx, QWORD PTR p$[rsp] 0007f 48 c7 44 24 48 00 00 00 00 mov QWORD PTR p$[rsp+24], 0 00088 85 db test ebx, ebx 0008a 74 41 je SHORT $LN14@stbi__png_ 0008c 8b 51 0c mov edx, DWORD PTR [rcx+12] 0008f 3b da cmp ebx, edx 00091 74 3a je SHORT $LN14@stbi__png_ ; 4797 : if (ri->bits_per_channel == 8) 00093 44 8b 09 mov r9d, DWORD PTR [rcx] 00096 83 f8 08 cmp eax, 8 00099 8b 41 04 mov eax, DWORD PTR [rcx+4] 0009c 44 8b c3 mov r8d, ebx 0009f 89 44 24 20 mov DWORD PTR [rsp+32], eax 000a3 48 8b cf mov rcx, rdi 000a6 75 07 jne SHORT $LN12@stbi__png_ ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 000a8 e8 00 00 00 00 call stbi__convert_format 000ad eb 05 jmp SHORT $LN33@stbi__png_ $LN12@stbi__png_: ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); 000af e8 00 00 00 00 call stbi__convert_format16 $LN33@stbi__png_: ; 4801 : p->s->img_out_n = req_comp; 000b4 48 8b f8 mov rdi, rax 000b7 48 8b 44 24 30 mov rax, QWORD PTR p$[rsp] 000bc 89 58 0c mov DWORD PTR [rax+12], ebx ; 4802 : if (result == NULL) return result; 000bf 48 85 ff test rdi, rdi 000c2 0f 84 9d 00 00 00 je $LN34@stbi__png_ 000c8 48 8b 4c 24 30 mov rcx, QWORD PTR p$[rsp] $LN14@stbi__png_: ; 4803 : } ; 4804 : *x = p->s->img_x; 000cd 8b 01 mov eax, DWORD PTR [rcx] 000cf 41 89 07 mov DWORD PTR [r15], eax ; 4805 : *y = p->s->img_y; 000d2 8b 41 04 mov eax, DWORD PTR [rcx+4] 000d5 89 45 00 mov DWORD PTR [rbp], eax ; 4806 : if (n) *n = p->s->img_n; 000d8 48 85 f6 test rsi, rsi 000db 74 05 je SHORT $LN23@stbi__png_ 000dd 8b 41 08 mov eax, DWORD PTR [rcx+8] 000e0 89 06 mov DWORD PTR [rsi], eax $LN23@stbi__png_: ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; 000e2 48 8b 4c 24 48 mov rcx, QWORD PTR p$[rsp+24] 000e7 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; 000ed 48 8b 4c 24 40 mov rcx, QWORD PTR p$[rsp+16] 000f2 48 c7 44 24 48 00 00 00 00 mov QWORD PTR p$[rsp+24], 0 000fb ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4810 : STBI_FREE(p->idata); p->idata = NULL; 00101 48 8b 4c 24 38 mov rcx, QWORD PTR p$[rsp+8] 00106 48 c7 44 24 40 00 00 00 00 mov QWORD PTR p$[rsp+16], 0 0010f ff 15 00 00 00 00 call QWORD PTR __imp_free ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); 00115 48 8b c7 mov rax, rdi ; 4812 : return result; 00118 eb 4d jmp SHORT $LN3@stbi__png_ $LN9@stbi__png_: ; 431 : stbi__g_failure_reason = str; 0011a 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00120 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00129 41 b9 00 00 00 00 mov r9d, OFFSET FLAT:stbi__g_failure_reason 0012f 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00133 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BF@NOEEEFMF@bad?5bits_per_channel@ 0013a 49 89 14 01 mov QWORD PTR [r9+rax], rdx ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); 0013e eb 25 jmp SHORT $LN34@stbi__png_ $LN5@stbi__png_: ; 431 : stbi__g_failure_reason = str; 00140 44 8b 05 00 00 00 00 mov r8d, DWORD PTR _tls_index 00147 65 48 8b 0c 25 58 00 00 00 mov rcx, QWORD PTR gs:88 00150 41 b9 00 00 00 00 mov r9d, OFFSET FLAT:stbi__g_failure_reason 00156 4a 8b 0c c1 mov rcx, QWORD PTR [rcx+r8*8] 0015a 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:??_C@_0N@KBPNPPBJ@bad?5req_comp@ 00161 4d 89 04 09 mov QWORD PTR [r9+rcx], r8 $LN34@stbi__png_: ; 4820 : } 00165 33 c0 xor eax, eax $LN3@stbi__png_: 00167 48 8b 4c 24 58 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0016c 48 33 cc xor rcx, rsp 0016f e8 00 00 00 00 call __security_check_cookie 00174 48 83 c4 68 add rsp, 104 ; 00000068H 00178 41 5f pop r15 0017a 41 5e pop r14 0017c 5f pop rdi 0017d 5e pop rsi 0017e 5d pop rbp 0017f 5b pop rbx 00180 c3 ret 0 stbi__png_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__png_test _TEXT SEGMENT s$ = 48 stbi__png_test PROC ; COMDAT ; 4823 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H 00006 48 8b d9 mov rbx, rcx ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); 00009 e8 00 00 00 00 call stbi__check_png_header ; 342 : s->img_buffer = s->img_buffer_original; 0000e 48 8b 93 d0 00 00 00 mov rdx, QWORD PTR [rbx+208] 00015 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0001c 48 8b 93 d8 00 00 00 mov rdx, QWORD PTR [rbx+216] 00023 48 89 93 c8 00 00 00 mov QWORD PTR [rbx+200], rdx ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } 0002a 48 83 c4 20 add rsp, 32 ; 00000020H 0002e 5b pop rbx 0002f c3 ret 0 stbi__png_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bmp_test_raw _TEXT SEGMENT s$ = 48 stbi__bmp_test_raw PROC ; COMDAT ; 4867 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 4867 : { 00011 48 8b f9 mov rdi, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 72 16 jb SHORT $LN34@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0001d 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00021 0f 84 cc 00 00 00 je $LN21@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00027 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0002c 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] $LN34@stbi__bmp_: ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; 00033 0f b6 08 movzx ecx, BYTE PTR [rax] 00036 48 ff c0 inc rax 00039 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00040 80 f9 42 cmp cl, 66 ; 00000042H 00043 0f 85 aa 00 00 00 jne $LN21@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00049 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00050 72 19 jb SHORT $LN35@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00052 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 00056 0f 84 97 00 00 00 je $LN21@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 0005c 48 8b cf mov rcx, rdi 0005f e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00064 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] $LN35@stbi__bmp_: ; 4871 : if (stbi__get8(s) != 'M') return 0; 0006b 0f b6 08 movzx ecx, BYTE PTR [rax] 0006e 48 ff c0 inc rax 00071 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00078 80 f9 4d cmp cl, 77 ; 0000004dH 0007b 75 76 jne SHORT $LN21@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 0007d 48 8b cf mov rcx, rdi 00080 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00085 48 8b cf mov rcx, rdi 00088 e8 00 00 00 00 call stbi__get16le ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved 0008d 48 8b cf mov rcx, rdi 00090 e8 00 00 00 00 call stbi__get16le ; 4874 : stbi__get16le(s); // discard reserved 00095 48 8b cf mov rcx, rdi 00098 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 0009d 48 8b cf mov rcx, rdi 000a0 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000a5 48 8b cf mov rcx, rdi 000a8 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 000ad 48 8b cf mov rcx, rdi 000b0 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000b5 48 8b cf mov rcx, rdi 000b8 8b d8 mov ebx, eax 000ba e8 00 00 00 00 call stbi__get16le 000bf c1 e0 10 shl eax, 16 000c2 03 c3 add eax, ebx ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); 000c4 83 f8 38 cmp eax, 56 ; 00000038H 000c7 77 10 ja SHORT $LN23@stbi__bmp_ 000c9 48 ba 00 10 00 00 00 01 00 01 mov rdx, 72058693549559808 ; 0100010000001000H 000d3 48 0f a3 c2 bt rdx, rax 000d7 72 0a jb SHORT $LN5@stbi__bmp_ $LN23@stbi__bmp_: 000d9 83 f8 6c cmp eax, 108 ; 0000006cH 000dc 74 05 je SHORT $LN5@stbi__bmp_ 000de 83 f8 7c cmp eax, 124 ; 0000007cH 000e1 75 10 jne SHORT $LN21@stbi__bmp_ $LN5@stbi__bmp_: 000e3 b8 01 00 00 00 mov eax, 1 ; 4878 : return r; ; 4879 : } 000e8 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000ed 48 83 c4 20 add rsp, 32 ; 00000020H 000f1 5f pop rdi 000f2 c3 ret 0 $LN21@stbi__bmp_: 000f3 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000f8 33 c0 xor eax, eax 000fa 48 83 c4 20 add rsp, 32 ; 00000020H 000fe 5f pop rdi 000ff c3 ret 0 stbi__bmp_test_raw ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bmp_test _TEXT SEGMENT s$ = 48 stbi__bmp_test PROC ; COMDAT ; 4882 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 4882 : { 00011 48 8b f9 mov rdi, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 72 16 jb SHORT $LN38@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0001d 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00021 0f 84 c3 00 00 00 je $LN26@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00027 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0002c 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] $LN38@stbi__bmp_: ; 4870 : if (stbi__get8(s) != 'B') return 0; 00033 0f b6 08 movzx ecx, BYTE PTR [rax] 00036 48 ff c0 inc rax 00039 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00040 80 f9 42 cmp cl, 66 ; 00000042H 00043 0f 85 a1 00 00 00 jne $LN26@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00049 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00050 72 19 jb SHORT $LN39@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00052 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 00056 0f 84 8e 00 00 00 je $LN26@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 0005c 48 8b cf mov rcx, rdi 0005f e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00064 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] $LN39@stbi__bmp_: ; 4871 : if (stbi__get8(s) != 'M') return 0; 0006b 0f b6 08 movzx ecx, BYTE PTR [rax] 0006e 48 ff c0 inc rax 00071 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00078 80 f9 4d cmp cl, 77 ; 0000004dH 0007b 75 6d jne SHORT $LN26@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 0007d 48 8b cf mov rcx, rdi 00080 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00085 48 8b cf mov rcx, rdi 00088 e8 00 00 00 00 call stbi__get16le ; 4873 : stbi__get16le(s); // discard reserved 0008d 48 8b cf mov rcx, rdi 00090 e8 00 00 00 00 call stbi__get16le ; 4874 : stbi__get16le(s); // discard reserved 00095 48 8b cf mov rcx, rdi 00098 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 0009d 48 8b cf mov rcx, rdi 000a0 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000a5 48 8b cf mov rcx, rdi 000a8 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 000ad 48 8b cf mov rcx, rdi 000b0 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000b5 48 8b cf mov rcx, rdi 000b8 8b d8 mov ebx, eax 000ba e8 00 00 00 00 call stbi__get16le 000bf c1 e0 10 shl eax, 16 000c2 03 c3 add eax, ebx ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); 000c4 83 f8 38 cmp eax, 56 ; 00000038H 000c7 77 10 ja SHORT $LN27@stbi__bmp_ 000c9 48 ba 00 10 00 00 00 01 00 01 mov rdx, 72058693549559808 ; 0100010000001000H 000d3 48 0f a3 c2 bt rdx, rax 000d7 72 0a jb SHORT $LN7@stbi__bmp_ $LN27@stbi__bmp_: 000d9 83 f8 6c cmp eax, 108 ; 0000006cH 000dc 74 05 je SHORT $LN7@stbi__bmp_ 000de 83 f8 7c cmp eax, 124 ; 0000007cH 000e1 75 07 jne SHORT $LN26@stbi__bmp_ $LN7@stbi__bmp_: 000e3 b8 01 00 00 00 mov eax, 1 ; 4878 : return r; 000e8 eb 02 jmp SHORT $LN3@stbi__bmp_ $LN26@stbi__bmp_: ; 342 : s->img_buffer = s->img_buffer_original; 000ea 33 c0 xor eax, eax $LN3@stbi__bmp_: 000ec 48 8b 8f d0 00 00 00 mov rcx, QWORD PTR [rdi+208] ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } 000f3 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] ; 342 : s->img_buffer = s->img_buffer_original; 000f8 48 89 8f c0 00 00 00 mov QWORD PTR [rdi+192], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 000ff 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] 00106 48 89 8f c8 00 00 00 mov QWORD PTR [rdi+200], rcx ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } 0010d 48 83 c4 20 add rsp, 32 ; 00000020H 00111 5f pop rdi 00112 c3 ret 0 stbi__bmp_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__high_bit _TEXT SEGMENT z$ = 8 stbi__high_bit PROC ; COMDAT ; 4890 : { 00000 8b c1 mov eax, ecx ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; 00002 85 c9 test ecx, ecx 00004 75 06 jne SHORT $LN2@stbi__high 00006 b8 ff ff ff ff mov eax, -1 ; 4899 : } 0000b c3 ret 0 $LN2@stbi__high: ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } 0000c c1 e9 10 shr ecx, 16 0000f ba 10 00 00 00 mov edx, 16 00014 3d 00 00 01 00 cmp eax, 65536 ; 00010000H 00019 0f 42 c8 cmovb ecx, eax 0001c 45 33 c0 xor r8d, r8d 0001f 3d 00 00 01 00 cmp eax, 65536 ; 00010000H 00024 41 0f 42 d0 cmovb edx, r8d 00028 81 f9 00 01 00 00 cmp ecx, 256 ; 00000100H 0002e 72 06 jb SHORT $LN4@stbi__high 00030 83 c2 08 add edx, 8 00033 c1 e9 08 shr ecx, 8 $LN4@stbi__high: ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } 00036 44 8b c1 mov r8d, ecx 00039 8d 42 04 lea eax, DWORD PTR [rdx+4] 0003c 41 c1 e8 04 shr r8d, 4 00040 83 f9 10 cmp ecx, 16 00043 0f 42 c2 cmovb eax, edx 00046 44 0f 42 c1 cmovb r8d, ecx ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 0004a 41 83 f8 04 cmp r8d, 4 0004e 41 8b c8 mov ecx, r8d 00051 8d 50 02 lea edx, DWORD PTR [rax+2] 00054 0f 42 d0 cmovb edx, eax 00057 c1 e9 02 shr ecx, 2 0005a 41 83 f8 04 cmp r8d, 4 0005e 41 0f 42 c8 cmovb ecx, r8d ; 4898 : return n; 00062 83 f9 02 cmp ecx, 2 00065 8d 42 01 lea eax, DWORD PTR [rdx+1] 00068 0f 42 c2 cmovb eax, edx ; 4899 : } 0006b c3 ret 0 stbi__high_bit ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bitcount _TEXT SEGMENT a$ = 8 stbi__bitcount PROC ; COMDAT ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00000 8b d1 mov edx, ecx 00002 81 e1 55 55 55 55 and ecx, 1431655765 ; 55555555H 00008 d1 ea shr edx, 1 0000a 81 e2 55 55 55 55 and edx, 1431655765 ; 55555555H 00010 03 d1 add edx, ecx ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 00012 8b c2 mov eax, edx 00014 81 e2 33 33 33 33 and edx, 858993459 ; 33333333H 0001a c1 e8 02 shr eax, 2 0001d 25 33 33 33 33 and eax, 858993459 ; 33333333H 00022 03 c2 add eax, edx ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 00024 8b c8 mov ecx, eax 00026 c1 e9 04 shr ecx, 4 00029 03 c8 add ecx, eax 0002b 81 e1 0f 0f 0f 0f and ecx, 252645135 ; 0f0f0f0fH ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits 00031 8b c1 mov eax, ecx 00033 c1 e8 08 shr eax, 8 00036 03 c8 add ecx, eax ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits 00038 8b c1 mov eax, ecx 0003a c1 e8 10 shr eax, 16 0003d 03 c1 add eax, ecx ; 4908 : return a & 0xff; 0003f 0f b6 c0 movzx eax, al ; 4909 : } 00042 c3 ret 0 stbi__bitcount ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__shiftsigned _TEXT SEGMENT v$ = 8 shift$ = 16 bits$ = 24 stbi__shiftsigned PROC ; COMDAT ; 4915 : { 00000 44 8b c9 mov r9d, ecx ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) 00003 85 d2 test edx, edx 00005 79 0a jns SHORT $LN2@stbi__shif ; 4925 : v <<= -shift; 00007 f7 da neg edx 00009 0f b6 ca movzx ecx, dl 0000c 41 d3 e1 shl r9d, cl 0000f eb 05 jmp SHORT $LN3@stbi__shif $LN2@stbi__shif: ; 4926 : else ; 4927 : v >>= shift; 00011 8b ca mov ecx, edx 00013 41 d3 e9 shr r9d, cl $LN3@stbi__shif: ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 00016 49 63 c0 movsxd rax, r8d 00019 b9 08 00 00 00 mov ecx, 8 0001e 41 2b c8 sub ecx, r8d 00021 41 d3 e9 shr r9d, cl 00024 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:__ImageBase 0002b 44 0f af 8c 81 00 00 00 00 imul r9d, DWORD PTR ?mul_table@?1??stbi__shiftsigned@@9@9[rcx+rax*4] 00034 8b 8c 81 00 00 00 00 mov ecx, DWORD PTR ?shift_table@?1??stbi__shiftsigned@@9@9[rcx+rax*4] 0003b 41 d3 f9 sar r9d, cl 0003e 41 8b c1 mov eax, r9d ; 4932 : } 00041 c3 ret 0 stbi__shiftsigned ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bmp_set_mask_defaults _TEXT SEGMENT info$ = 8 compress$ = 16 stbi__bmp_set_mask_defaults PROC ; COMDAT ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) 00000 83 fa 03 cmp edx, 3 00003 74 20 je SHORT $LN7@stbi__bmp_ ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { 00005 85 d2 test edx, edx 00007 75 5e jne SHORT $LN3@stbi__bmp_ ; 4948 : if (info->bpp == 16) { 00009 8b 01 mov eax, DWORD PTR [rcx] 0000b 83 f8 10 cmp eax, 16 0000e 75 1b jne SHORT $LN4@stbi__bmp_ ; 4949 : info->mr = 31u << 10; 00010 c7 41 0c 00 7c 00 00 mov DWORD PTR [rcx+12], 31744 ; 00007c00H ; 4950 : info->mg = 31u << 5; 00017 c7 41 10 e0 03 00 00 mov DWORD PTR [rcx+16], 992 ; 000003e0H ; 4951 : info->mb = 31u << 0; 0001e c7 41 14 1f 00 00 00 mov DWORD PTR [rcx+20], 31 $LN7@stbi__bmp_: ; 4963 : } ; 4964 : return 1; 00025 b8 01 00 00 00 mov eax, 1 ; 4967 : } 0002a c3 ret 0 $LN4@stbi__bmp_: ; 4952 : } ; 4953 : else if (info->bpp == 32) { 0002b 83 f8 20 cmp eax, 32 ; 00000020H 0002e 75 27 jne SHORT $LN6@stbi__bmp_ ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 00030 33 c0 xor eax, eax 00032 c7 41 0c 00 00 ff 00 mov DWORD PTR [rcx+12], 16711680 ; 00ff0000H 00039 89 41 1c mov DWORD PTR [rcx+28], eax ; 4963 : } ; 4964 : return 1; 0003c b8 01 00 00 00 mov eax, 1 00041 c7 41 10 00 ff 00 00 mov DWORD PTR [rcx+16], 65280 ; 0000ff00H 00048 c7 41 14 ff 00 00 00 mov DWORD PTR [rcx+20], 255 ; 000000ffH 0004f c7 41 18 00 00 00 ff mov DWORD PTR [rcx+24], -16777216 ; ff000000H ; 4967 : } 00056 c3 ret 0 $LN6@stbi__bmp_: ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; 00057 33 c0 xor eax, eax 00059 48 89 41 14 mov QWORD PTR [rcx+20], rax 0005d 48 89 41 0c mov QWORD PTR [rcx+12], rax ; 4963 : } ; 4964 : return 1; 00061 b8 01 00 00 00 mov eax, 1 ; 4967 : } 00066 c3 ret 0 $LN3@stbi__bmp_: ; 4965 : } ; 4966 : return 0; // error 00067 33 c0 xor eax, eax ; 4967 : } 00069 c3 ret 0 stbi__bmp_set_mask_defaults ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bmp_parse_header _TEXT SEGMENT s$ = 64 info$ = 72 stbi__bmp_parse_header PROC ; COMDAT ; 4970 : { 00000 40 53 push rbx 00002 56 push rsi 00003 57 push rdi 00004 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 00008 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 4970 : { 0000f 48 8b f2 mov rsi, rdx 00012 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00015 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001c 72 16 jb SHORT $LN179@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0001e 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00022 0f 84 38 05 00 00 je $LN6@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00028 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0002d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN179@stbi__bmp_: ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); 00034 0f b6 08 movzx ecx, BYTE PTR [rax] 00037 48 ff c0 inc rax 0003a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00041 80 f9 42 cmp cl, 66 ; 00000042H 00044 0f 85 16 05 00 00 jne $LN6@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0004a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00051 72 19 jb SHORT $LN180@stbi__bmp_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00053 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00057 0f 84 03 05 00 00 je $LN6@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 0005d 48 8b cb mov rcx, rbx 00060 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00065 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN180@stbi__bmp_: ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); 0006c 0f b6 08 movzx ecx, BYTE PTR [rax] 0006f 48 ff c0 inc rax 00072 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00079 80 f9 4d cmp cl, 77 ; 0000004dH 0007c 0f 85 de 04 00 00 jne $LN6@stbi__bmp_ 00082 48 89 6c 24 40 mov QWORD PTR [rsp+64], rbp ; 1186 : stbi__uint32 z = stbi__get16le(s); 00087 48 8b cb mov rcx, rbx ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); 0008a 4c 89 7c 24 50 mov QWORD PTR [rsp+80], r15 ; 1186 : stbi__uint32 z = stbi__get16le(s); 0008f e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00094 48 8b cb mov rcx, rbx 00097 e8 00 00 00 00 call stbi__get16le ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved 0009c 48 8b cb mov rcx, rbx 0009f e8 00 00 00 00 call stbi__get16le ; 4975 : stbi__get16le(s); // discard reserved 000a4 48 8b cb mov rcx, rbx 000a7 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 000ac 48 8b cb mov rcx, rbx 000af e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000b4 48 8b cb mov rcx, rbx 000b7 8b f8 mov edi, eax 000b9 e8 00 00 00 00 call stbi__get16le 000be c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 000c1 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000c4 03 c7 add eax, edi ; 4976 : info->offset = stbi__get32le(s); 000c6 89 46 04 mov DWORD PTR [rsi+4], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 000c9 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000ce 48 8b cb mov rcx, rbx 000d1 8b f8 mov edi, eax 000d3 e8 00 00 00 00 call stbi__get16le ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; 000d8 45 33 ff xor r15d, r15d ; 4979 : info->extra_read = 14; 000db c7 46 20 0e 00 00 00 mov DWORD PTR [rsi+32], 14 ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000e2 8b e8 mov ebp, eax ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; 000e4 4c 89 7e 14 mov QWORD PTR [rsi+20], r15 ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 000e8 c1 e5 10 shl ebp, 16 000eb 03 ef add ebp, edi ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; 000ed 4c 89 7e 0c mov QWORD PTR [rsi+12], r15 000f1 89 6e 08 mov DWORD PTR [rsi+8], ebp ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); 000f4 44 39 7e 04 cmp DWORD PTR [rsi+4], r15d 000f8 0f 8c 97 00 00 00 jl $LN182@stbi__bmp_ ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); 000fe 83 fd 38 cmp ebp, 56 ; 00000038H 00101 77 10 ja SHORT $LN137@stbi__bmp_ 00103 48 b9 00 10 00 00 00 01 00 01 mov rcx, 72058693549559808 ; 0100010000001000H 0010d 48 0f a3 e9 bt rcx, rbp 00111 72 34 jb SHORT $LN8@stbi__bmp_ $LN137@stbi__bmp_: 00113 83 fd 6c cmp ebp, 108 ; 0000006cH 00116 74 2f je SHORT $LN8@stbi__bmp_ 00118 83 fd 7c cmp ebp, 124 ; 0000007cH 0011b 74 2a je SHORT $LN8@stbi__bmp_ ; 431 : stbi__g_failure_reason = str; 0011d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00123 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0012c b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00131 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00135 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@KHBIBJBG@unknown?5BMP@ 0013c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); 00140 33 c0 xor eax, eax 00142 e9 e6 00 00 00 jmp $LN177@stbi__bmp_ $LN8@stbi__bmp_: ; 4984 : if (hsz == 12) { 00147 48 8b cb mov rcx, rbx 0014a e8 00 00 00 00 call stbi__get16le 0014f 48 8b cb mov rcx, rbx 00152 83 fd 0c cmp ebp, 12 00155 75 09 jne SHORT $LN9@stbi__bmp_ ; 4985 : s->img_x = stbi__get16le(s); 00157 89 03 mov DWORD PTR [rbx], eax ; 4986 : s->img_y = stbi__get16le(s); 00159 e8 00 00 00 00 call stbi__get16le ; 4987 : } 0015e eb 25 jmp SHORT $LN10@stbi__bmp_ $LN9@stbi__bmp_: ; 1186 : stbi__uint32 z = stbi__get16le(s); 00160 8b f8 mov edi, eax ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00162 e8 00 00 00 00 call stbi__get16le 00167 c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 0016a 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0016d 03 c7 add eax, edi ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); 0016f 89 03 mov DWORD PTR [rbx], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 00171 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00176 48 8b cb mov rcx, rbx 00179 8b f8 mov edi, eax 0017b e8 00 00 00 00 call stbi__get16le 00180 c1 e0 10 shl eax, 16 00183 03 c7 add eax, edi $LN10@stbi__bmp_: ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); 00185 48 8b cb mov rcx, rbx 00188 89 43 04 mov DWORD PTR [rbx+4], eax 0018b e8 00 00 00 00 call stbi__get16le 00190 83 f8 01 cmp eax, 1 00193 74 27 je SHORT $LN11@stbi__bmp_ $LN182@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 00195 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0019b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001a4 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 001a9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001ad 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07IEJCHBDI@bad?5BMP@ 001b4 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); 001b8 33 c0 xor eax, eax 001ba eb 71 jmp SHORT $LN177@stbi__bmp_ $LN11@stbi__bmp_: ; 4993 : info->bpp = stbi__get16le(s); 001bc 48 8b cb mov rcx, rbx 001bf 4c 89 74 24 48 mov QWORD PTR [rsp+72], r14 001c4 e8 00 00 00 00 call stbi__get16le 001c9 89 06 mov DWORD PTR [rsi], eax ; 4994 : if (hsz != 12) { 001cb 83 fd 0c cmp ebp, 12 001ce 0f 84 1b 02 00 00 je $LN30@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 001d4 48 8b cb mov rcx, rbx 001d7 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 001dc 48 8b cb mov rcx, rbx 001df 8b f8 mov edi, eax 001e1 e8 00 00 00 00 call stbi__get16le 001e6 44 8b f0 mov r14d, eax 001e9 41 c1 e6 10 shl r14d, 16 001ed 44 03 f7 add r14d, edi ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); 001f0 41 8d 4e ff lea ecx, DWORD PTR [r14-1] 001f4 83 f9 01 cmp ecx, 1 001f7 0f 86 3f 03 00 00 jbe $LN14@stbi__bmp_ ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes 001fd 41 83 fe 04 cmp r14d, 4 00201 7c 3c jl SHORT $LN15@stbi__bmp_ ; 431 : stbi__g_failure_reason = str; 00203 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00209 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00212 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00217 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0021b 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@ODCBCBFN@BMP?5JPEG?1PNG@ $LN181@stbi__bmp_: 00222 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); 00226 33 c0 xor eax, eax $LN178@stbi__bmp_: 00228 4c 8b 74 24 48 mov r14, QWORD PTR [rsp+72] $LN177@stbi__bmp_: 0022d 48 8b 6c 24 40 mov rbp, QWORD PTR [rsp+64] 00232 4c 8b 7c 24 50 mov r15, QWORD PTR [rsp+80] ; 5053 : } 00237 48 83 c4 20 add rsp, 32 ; 00000020H 0023b 5f pop rdi 0023c 5e pop rsi 0023d 5b pop rbx 0023e c3 ret 0 $LN15@stbi__bmp_: ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel 0023f 41 83 fe 03 cmp r14d, 3 00243 75 10 jne SHORT $LN16@stbi__bmp_ 00245 8b 06 mov eax, DWORD PTR [rsi] 00247 83 e8 10 sub eax, 16 0024a a9 ef ff ff ff test eax, -17 ; ffffffefH 0024f 0f 85 c3 02 00 00 jne $LN25@stbi__bmp_ $LN16@stbi__bmp_: ; 1186 : stbi__uint32 z = stbi__get16le(s); 00255 48 8b cb mov rcx, rbx 00258 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0025d 48 8b cb mov rcx, rbx 00260 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00265 48 8b cb mov rcx, rbx 00268 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0026d 48 8b cb mov rcx, rbx 00270 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00275 48 8b cb mov rcx, rbx 00278 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0027d 48 8b cb mov rcx, rbx 00280 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00285 48 8b cb mov rcx, rbx 00288 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0028d 48 8b cb mov rcx, rbx 00290 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00295 48 8b cb mov rcx, rbx 00298 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0029d 48 8b cb mov rcx, rbx 002a0 e8 00 00 00 00 call stbi__get16le ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { 002a5 83 fd 28 cmp ebp, 40 ; 00000028H 002a8 0f 84 8b 01 00 00 je $LN20@stbi__bmp_ 002ae 83 fd 38 cmp ebp, 56 ; 00000038H 002b1 0f 84 42 01 00 00 je $LN136@stbi__bmp_ ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) 002b7 8d 45 94 lea eax, DWORD PTR [rbp-108] 002ba a9 ef ff ff ff test eax, -17 ; ffffffefH 002bf 0f 85 53 02 00 00 jne $LN25@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 002c5 48 8b cb mov rcx, rbx 002c8 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 002cd 48 8b cb mov rcx, rbx 002d0 8b f8 mov edi, eax 002d2 e8 00 00 00 00 call stbi__get16le 002d7 c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 002da 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 002dd 03 c7 add eax, edi ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); 002df 89 46 0c mov DWORD PTR [rsi+12], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 002e2 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 002e7 48 8b cb mov rcx, rbx 002ea 8b f8 mov edi, eax 002ec e8 00 00 00 00 call stbi__get16le 002f1 c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 002f4 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 002f7 03 c7 add eax, edi ; 5036 : info->mg = stbi__get32le(s); 002f9 89 46 10 mov DWORD PTR [rsi+16], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 002fc e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00301 48 8b cb mov rcx, rbx 00304 8b f8 mov edi, eax 00306 e8 00 00 00 00 call stbi__get16le 0030b c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 0030e 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00311 03 c7 add eax, edi ; 5037 : info->mb = stbi__get32le(s); 00313 89 46 14 mov DWORD PTR [rsi+20], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 00316 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0031b 48 8b cb mov rcx, rbx 0031e 8b f8 mov edi, eax 00320 e8 00 00 00 00 call stbi__get16le 00325 c1 e0 10 shl eax, 16 00328 03 c7 add eax, edi ; 5038 : info->ma = stbi__get32le(s); 0032a 89 46 18 mov DWORD PTR [rsi+24], eax ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs 0032d 45 85 f6 test r14d, r14d 00330 75 4d jne SHORT $LN126@stbi__bmp_ ; 4948 : if (info->bpp == 16) { 00332 8b 06 mov eax, DWORD PTR [rsi] 00334 83 f8 10 cmp eax, 16 00337 75 17 jne SHORT $LN123@stbi__bmp_ ; 4949 : info->mr = 31u << 10; 00339 c7 46 0c 00 7c 00 00 mov DWORD PTR [rsi+12], 31744 ; 00007c00H ; 4950 : info->mg = 31u << 5; 00340 c7 46 10 e0 03 00 00 mov DWORD PTR [rsi+16], 992 ; 000003e0H ; 4951 : info->mb = 31u << 0; 00347 c7 46 14 1f 00 00 00 mov DWORD PTR [rsi+20], 31 ; 4952 : } 0034e eb 2f jmp SHORT $LN126@stbi__bmp_ $LN123@stbi__bmp_: ; 4953 : else if (info->bpp == 32) { 00350 83 f8 20 cmp eax, 32 ; 00000020H 00353 75 22 jne SHORT $LN125@stbi__bmp_ ; 4954 : info->mr = 0xffu << 16; 00355 c7 46 0c 00 00 ff 00 mov DWORD PTR [rsi+12], 16711680 ; 00ff0000H ; 4955 : info->mg = 0xffu << 8; 0035c c7 46 10 00 ff 00 00 mov DWORD PTR [rsi+16], 65280 ; 0000ff00H ; 4956 : info->mb = 0xffu << 0; 00363 c7 46 14 ff 00 00 00 mov DWORD PTR [rsi+20], 255 ; 000000ffH ; 4957 : info->ma = 0xffu << 24; 0036a c7 46 18 00 00 00 ff mov DWORD PTR [rsi+24], -16777216 ; ff000000H ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 00371 44 89 7e 1c mov DWORD PTR [rsi+28], r15d ; 4959 : } 00375 eb 08 jmp SHORT $LN126@stbi__bmp_ $LN125@stbi__bmp_: ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; 00377 4c 89 7e 14 mov QWORD PTR [rsi+20], r15 0037b 4c 89 7e 0c mov QWORD PTR [rsi+12], r15 $LN126@stbi__bmp_: ; 1186 : stbi__uint32 z = stbi__get16le(s); 0037f 48 8b cb mov rcx, rbx 00382 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00387 48 8b cb mov rcx, rbx 0038a e8 00 00 00 00 call stbi__get16le 0038f bf 0c 00 00 00 mov edi, 12 $LL4@stbi__bmp_: ; 1186 : stbi__uint32 z = stbi__get16le(s); 00394 48 8b cb mov rcx, rbx 00397 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 0039c 48 8b cb mov rcx, rbx 0039f e8 00 00 00 00 call stbi__get16le ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) 003a4 48 83 ef 01 sub rdi, 1 003a8 75 ea jne SHORT $LL4@stbi__bmp_ ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { 003aa 83 fd 7c cmp ebp, 124 ; 0000007cH 003ad 75 40 jne SHORT $LN30@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 003af 48 8b cb mov rcx, rbx 003b2 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 003b7 48 8b cb mov rcx, rbx 003ba e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 003bf 48 8b cb mov rcx, rbx 003c2 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 003c7 48 8b cb mov rcx, rbx 003ca e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 003cf 48 8b cb mov rcx, rbx 003d2 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 003d7 48 8b cb mov rcx, rbx 003da e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 003df 48 8b cb mov rcx, rbx 003e2 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 003e7 48 8b cb mov rcx, rbx 003ea e8 00 00 00 00 call stbi__get16le $LN30@stbi__bmp_: ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 003ef b8 01 00 00 00 mov eax, 1 003f4 e9 2f fe ff ff jmp $LN178@stbi__bmp_ $LN136@stbi__bmp_: ; 1186 : stbi__uint32 z = stbi__get16le(s); 003f9 48 8b cb mov rcx, rbx 003fc e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00401 48 8b cb mov rcx, rbx 00404 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00409 48 8b cb mov rcx, rbx 0040c e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00411 48 8b cb mov rcx, rbx 00414 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00419 48 8b cb mov rcx, rbx 0041c e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00421 48 8b cb mov rcx, rbx 00424 e8 00 00 00 00 call stbi__get16le ; 1186 : stbi__uint32 z = stbi__get16le(s); 00429 48 8b cb mov rcx, rbx 0042c e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00431 48 8b cb mov rcx, rbx 00434 e8 00 00 00 00 call stbi__get16le $LN20@stbi__bmp_: ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { 00439 8b 0e mov ecx, DWORD PTR [rsi] 0043b 8d 41 f0 lea eax, DWORD PTR [rcx-16] 0043e a9 ef ff ff ff test eax, -17 ; ffffffefH 00443 75 aa jne SHORT $LN30@stbi__bmp_ ; 5012 : if (compress == 0) { 00445 45 85 f6 test r14d, r14d 00448 75 61 jne SHORT $LN23@stbi__bmp_ ; 4948 : if (info->bpp == 16) { 0044a 83 f9 10 cmp ecx, 16 0044d 75 1d jne SHORT $LN95@stbi__bmp_ ; 4949 : info->mr = 31u << 10; 0044f c7 46 0c 00 7c 00 00 mov DWORD PTR [rsi+12], 31744 ; 00007c00H ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 00456 8d 41 f1 lea eax, QWORD PTR [rcx-15] ; 4950 : info->mg = 31u << 5; 00459 c7 46 10 e0 03 00 00 mov DWORD PTR [rsi+16], 992 ; 000003e0H ; 4951 : info->mb = 31u << 0; 00460 c7 46 14 1f 00 00 00 mov DWORD PTR [rsi+20], 31 ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 00467 e9 bc fd ff ff jmp $LN178@stbi__bmp_ $LN95@stbi__bmp_: ; 4953 : else if (info->bpp == 32) { 0046c 83 f9 20 cmp ecx, 32 ; 00000020H 0046f 75 28 jne SHORT $LN97@stbi__bmp_ ; 4954 : info->mr = 0xffu << 16; 00471 c7 46 0c 00 00 ff 00 mov DWORD PTR [rsi+12], 16711680 ; 00ff0000H ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 00478 8d 41 e1 lea eax, QWORD PTR [rcx-31] ; 4955 : info->mg = 0xffu << 8; 0047b c7 46 10 00 ff 00 00 mov DWORD PTR [rsi+16], 65280 ; 0000ff00H ; 4956 : info->mb = 0xffu << 0; 00482 c7 46 14 ff 00 00 00 mov DWORD PTR [rsi+20], 255 ; 000000ffH ; 4957 : info->ma = 0xffu << 24; 00489 c7 46 18 00 00 00 ff mov DWORD PTR [rsi+24], -16777216 ; ff000000H ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 00490 44 89 7e 1c mov DWORD PTR [rsi+28], r15d ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 00494 e9 8f fd ff ff jmp $LN178@stbi__bmp_ $LN97@stbi__bmp_: ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; 00499 4c 89 7e 14 mov QWORD PTR [rsi+20], r15 ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 0049d b8 01 00 00 00 mov eax, 1 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; 004a2 4c 89 7e 0c mov QWORD PTR [rsi+12], r15 ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; 004a6 e9 7d fd ff ff jmp $LN178@stbi__bmp_ $LN23@stbi__bmp_: ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { 004ab 41 83 fe 03 cmp r14d, 3 004af 75 67 jne SHORT $LN25@stbi__bmp_ ; 1186 : stbi__uint32 z = stbi__get16le(s); 004b1 48 8b cb mov rcx, rbx 004b4 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004b9 48 8b cb mov rcx, rbx 004bc 8b f8 mov edi, eax 004be e8 00 00 00 00 call stbi__get16le 004c3 c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 004c6 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004c9 03 c7 add eax, edi ; 5016 : info->mr = stbi__get32le(s); 004cb 89 46 0c mov DWORD PTR [rsi+12], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 004ce e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004d3 48 8b cb mov rcx, rbx 004d6 8b f8 mov edi, eax 004d8 e8 00 00 00 00 call stbi__get16le 004dd c1 e0 10 shl eax, 16 ; 1186 : stbi__uint32 z = stbi__get16le(s); 004e0 48 8b cb mov rcx, rbx ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004e3 03 c7 add eax, edi ; 5017 : info->mg = stbi__get32le(s); 004e5 89 46 10 mov DWORD PTR [rsi+16], eax ; 1186 : stbi__uint32 z = stbi__get16le(s); 004e8 e8 00 00 00 00 call stbi__get16le ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004ed 48 8b cb mov rcx, rbx 004f0 8b f8 mov edi, eax 004f2 e8 00 00 00 00 call stbi__get16le ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; 004f7 83 46 20 0c add DWORD PTR [rsi+32], 12 ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 004fb c1 e0 10 shl eax, 16 004fe 8d 0c 38 lea ecx, DWORD PTR [rax+rdi] ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { 00501 8b 46 10 mov eax, DWORD PTR [rsi+16] 00504 89 4e 14 mov DWORD PTR [rsi+20], ecx 00507 39 46 0c cmp DWORD PTR [rsi+12], eax 0050a 0f 85 df fe ff ff jne $LN30@stbi__bmp_ 00510 3b c1 cmp eax, ecx 00512 0f 85 d7 fe ff ff jne $LN30@stbi__bmp_ $LN25@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 00518 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0051e 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00527 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0052c 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00530 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07IEJCHBDI@bad?5BMP@ ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); 00537 e9 e6 fc ff ff jmp $LN181@stbi__bmp_ $LN14@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 0053c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00542 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0054b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00550 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00554 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07IMHMNOIB@BMP?5RLE@ ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); 0055b e9 c2 fc ff ff jmp $LN181@stbi__bmp_ $LN6@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 00560 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00566 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0056f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00574 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00578 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07IANEBNLB@not?5BMP@ 0057f 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); 00583 33 c0 xor eax, eax ; 5053 : } 00585 48 83 c4 20 add rsp, 32 ; 00000020H 00589 5f pop rdi 0058a 5e pop rsi 0058b 5b pop rbx 0058c c3 ret 0 stbi__bmp_parse_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__bmp_load _TEXT SEGMENT ashift$1$ = 48 pad$1$ = 48 info$2$ = 48 pad$2$ = 52 info$5$ = 52 all_a$1$ = 56 n$1$ = 60 bshift$1$ = 60 info$3$ = 64 gshift$1$ = 68 mr$1$ = 72 mg$1$ = 76 mb$1$ = 80 $T22 = 88 rshift$1$ = 96 ma$1$ = 100 tv4035 = 108 tv4034 = 112 tv4033 = 116 tv4032 = 120 tv4030 = 124 tv4029 = 128 tv4028 = 132 tv4027 = 136 tv4126 = 140 out$1$ = 144 tv4023 = 152 info$ = 160 tv4026 = 200 tv4025 = 208 tv4024 = 216 pal$ = 224 s$ = 1312 x$ = 1320 y$ = 1328 comp$ = 1336 req_comp$ = 1344 j$3$ = 1352 target$4$ = 1352 ri$dead$ = 1352 stbi__bmp_load PROC ; COMDAT ; 5056 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 4c 89 4c 24 20 mov QWORD PTR [rsp+32], r9 0000a 4c 89 44 24 18 mov QWORD PTR [rsp+24], r8 0000f 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx 00014 55 push rbp 00015 56 push rsi 00016 57 push rdi 00017 41 54 push r12 00019 41 55 push r13 0001b 41 56 push r14 0001d 41 57 push r15 0001f 48 81 ec e0 04 00 00 sub rsp, 1248 ; 000004e0H ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; 00026 45 33 ff xor r15d, r15d ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; 00029 c7 84 24 bc 00 00 00 ff 00 00 00 mov DWORD PTR info$[rsp+28], 255 ; 000000ffH ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) 00034 48 8d 94 24 a0 00 00 00 lea rdx, QWORD PTR info$[rsp] 0003c 45 8b e7 mov r12d, r15d 0003f 48 8b d9 mov rbx, rcx 00042 e8 00 00 00 00 call stbi__bmp_parse_header 00047 48 85 c0 test rax, rax 0004a 0f 84 99 12 00 00 je $LN373@stbi__bmp_ ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; 00050 8b 4b 04 mov ecx, DWORD PTR [rbx+4] ; 5070 : s->img_y = abs((int)s->img_y); 00053 8b c1 mov eax, ecx 00055 f7 d8 neg eax 00057 89 8c 24 8c 00 00 00 mov DWORD PTR tv4126[rsp], ecx 0005e 0f 48 c1 cmovs eax, ecx 00061 89 43 04 mov DWORD PTR [rbx+4], eax ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 00064 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 00069 76 1f jbe SHORT $LN36@stbi__bmp_ $LN527@stbi__bmp_: ; 5262 : } 0006b 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00071 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0007a 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0007e 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 00085 e9 56 12 00 00 jmp $LN528@stbi__bmp_ $LN36@stbi__bmp_: ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0008a 81 3b 00 00 00 01 cmp DWORD PTR [rbx], 16777216 ; 01000000H 00090 77 d9 ja SHORT $LN527@stbi__bmp_ ; 5074 : ; 5075 : mr = info.mr; 00092 8b 84 24 ac 00 00 00 mov eax, DWORD PTR info$[rsp+12] ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { 00099 8b ac 24 a8 00 00 00 mov ebp, DWORD PTR info$[rsp+8] 000a0 8b b4 24 b8 00 00 00 mov esi, DWORD PTR info$[rsp+24] 000a7 44 8b b4 24 a4 00 00 00 mov r14d, DWORD PTR info$[rsp+4] 000af 8b bc 24 a0 00 00 00 mov edi, DWORD PTR info$[rsp] 000b6 89 44 24 48 mov DWORD PTR mr$1$[rsp], eax 000ba 8b 84 24 b0 00 00 00 mov eax, DWORD PTR info$[rsp+16] 000c1 89 44 24 4c mov DWORD PTR mg$1$[rsp], eax 000c5 8b 84 24 b4 00 00 00 mov eax, DWORD PTR info$[rsp+20] 000cc 89 44 24 50 mov DWORD PTR mb$1$[rsp], eax 000d0 8b 84 24 bc 00 00 00 mov eax, DWORD PTR info$[rsp+28] 000d7 89 44 24 38 mov DWORD PTR all_a$1$[rsp], eax 000db 8b 84 24 c0 00 00 00 mov eax, DWORD PTR info$[rsp+32] 000e2 89 44 24 34 mov DWORD PTR info$5$[rsp], eax 000e6 89 74 24 64 mov DWORD PTR ma$1$[rsp], esi 000ea 44 89 74 24 3c mov DWORD PTR n$1$[rsp], r14d 000ef 89 6c 24 30 mov DWORD PTR info$2$[rsp], ebp 000f3 89 7c 24 40 mov DWORD PTR info$3$[rsp], edi 000f7 83 fd 0c cmp ebp, 12 000fa 75 20 jne SHORT $LN38@stbi__bmp_ ; 5082 : if (info.bpp < 24) 000fc 83 ff 18 cmp edi, 24 000ff 7d 36 jge SHORT $LN354@stbi__bmp_ ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; 00101 41 8b ce mov ecx, r14d 00104 2b c8 sub ecx, eax 00106 b8 56 55 55 55 mov eax, 1431655766 ; 55555556H 0010b 83 e9 18 sub ecx, 24 0010e f7 e9 imul ecx 00110 44 8b e2 mov r12d, edx 00113 41 c1 ec 1f shr r12d, 31 00117 44 03 e2 add r12d, edx ; 5084 : } 0011a eb 12 jmp SHORT $LN41@stbi__bmp_ $LN38@stbi__bmp_: ; 5085 : else { ; 5086 : if (info.bpp < 16) 0011c 83 ff 10 cmp edi, 16 0011f 7d 16 jge SHORT $LN354@stbi__bmp_ ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; 00121 45 8b e6 mov r12d, r14d 00124 44 2b e0 sub r12d, eax 00127 44 2b e5 sub r12d, ebp 0012a 41 c1 fc 02 sar r12d, 2 $LN41@stbi__bmp_: ; 5088 : } ; 5089 : if (psize == 0) { 0012e 45 85 e4 test r12d, r12d 00131 0f 85 8c 00 00 00 jne $LN254@stbi__bmp_ $LN354@stbi__bmp_: ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); 00137 8b 93 b8 00 00 00 mov edx, DWORD PTR [rbx+184] 0013d 2b 93 d0 00 00 00 sub edx, DWORD PTR [rbx+208] 00143 44 8b 83 c0 00 00 00 mov r8d, DWORD PTR [rbx+192] 0014a 41 03 d0 add edx, r8d ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { 0014d 8d 42 ff lea eax, DWORD PTR [rdx-1] 00150 3d ff 03 00 00 cmp eax, 1023 ; 000003ffH 00155 0f 87 6b 11 00 00 ja $LN44@stbi__bmp_ ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { 0015b 44 3b f2 cmp r14d, edx 0015e 0f 8c 46 11 00 00 jl $LN47@stbi__bmp_ 00164 41 8b ce mov ecx, r14d 00167 2b ca sub ecx, edx 00169 81 f9 00 04 00 00 cmp ecx, 1024 ; 00000400H 0016f 0f 8f 35 11 00 00 jg $LN47@stbi__bmp_ ; 1107 : if (n == 0) return; // already there! 00175 85 c9 test ecx, ecx 00177 74 4a je SHORT $LN254@stbi__bmp_ ; 1108 : if (n < 0) { 00179 79 10 jns SHORT $LN256@stbi__bmp_ ; 1109 : s->img_buffer = s->img_buffer_end; 0017b 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00182 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 1110 : return; 00189 eb 38 jmp SHORT $LN254@stbi__bmp_ $LN256@stbi__bmp_: ; 1111 : } ; 1112 : if (s->io.read) { 0018b 4c 39 7b 10 cmp QWORD PTR [rbx+16], r15 0018f 74 28 je SHORT $LN258@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00191 8b 93 c8 00 00 00 mov edx, DWORD PTR [rbx+200] 00197 41 2b d0 sub edx, r8d ; 1114 : if (blen < n) { 0019a 3b d1 cmp edx, ecx 0019c 7d 1b jge SHORT $LN258@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 0019e 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 001a5 2b ca sub ecx, edx 001a7 8b d1 mov edx, ecx 001a9 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001b0 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 001b4 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 001b7 eb 0a jmp SHORT $LN254@stbi__bmp_ $LN258@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 001b9 48 63 c1 movsxd rax, ecx 001bc 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN254@stbi__bmp_: ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) 001c3 83 ff 18 cmp edi, 24 001c6 75 0e jne SHORT $LN48@stbi__bmp_ 001c8 81 fe 00 00 00 ff cmp esi, -16777216 ; ff000000H 001ce 75 06 jne SHORT $LN48@stbi__bmp_ ; 5111 : s->img_n = 3; 001d0 44 8d 6f eb lea r13d, QWORD PTR [rdi-21] 001d4 eb 0d jmp SHORT $LN523@stbi__bmp_ $LN48@stbi__bmp_: ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; 001d6 85 f6 test esi, esi 001d8 45 8b ef mov r13d, r15d 001db 41 0f 95 c5 setne r13b 001df 41 83 c5 03 add r13d, 3 $LN523@stbi__bmp_: ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 001e3 8b 84 24 40 05 00 00 mov eax, DWORD PTR req_comp$[rsp] 001ea 44 89 6b 08 mov DWORD PTR [rbx+8], r13d 001ee 44 8b 4b 04 mov r9d, DWORD PTR [rbx+4] 001f2 45 8b d1 mov r10d, r9d 001f5 8b 0b mov ecx, DWORD PTR [rbx] 001f7 44 8b c1 mov r8d, ecx 001fa 44 89 ac 24 48 05 00 00 mov DWORD PTR target$4$[rsp], r13d 00202 83 f8 03 cmp eax, 3 00205 7c 0a jl SHORT $LN369@stbi__bmp_ ; 5115 : target = req_comp; 00207 44 8b e8 mov r13d, eax 0020a 89 84 24 48 05 00 00 mov DWORD PTR target$4$[rsp], eax $LN369@stbi__bmp_: ; 467 : if (a < 0 || b < 0) return 0; 00211 45 85 c0 test r8d, r8d 00214 0f 88 51 fe ff ff js $LN527@stbi__bmp_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0021a 74 12 je SHORT $LN368@stbi__bmp_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0021c b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00221 99 cdq 00222 41 f7 f8 idiv r8d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00225 44 3b e8 cmp r13d, eax 00228 0f 8f 3d fe ff ff jg $LN527@stbi__bmp_ $LN368@stbi__bmp_: 0022e 45 0f af c5 imul r8d, r13d ; 467 : if (a < 0 || b < 0) return 0; 00232 45 85 c0 test r8d, r8d 00235 0f 88 30 fe ff ff js $LN527@stbi__bmp_ 0023b 45 85 d2 test r10d, r10d 0023e 0f 88 27 fe ff ff js $LN527@stbi__bmp_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00244 74 12 je SHORT $LN52@stbi__bmp_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00246 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0024b 99 cdq 0024c 41 f7 fa idiv r10d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0024f 44 3b c0 cmp r8d, eax 00252 0f 8f 13 fe ff ff jg $LN527@stbi__bmp_ $LN52@stbi__bmp_: ; 467 : if (a < 0 || b < 0) return 0; 00258 45 85 ed test r13d, r13d 0025b 0f 88 2d 10 00 00 js $LN355@stbi__bmp_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00261 85 c9 test ecx, ecx 00263 75 09 jne SHORT $LN186@stbi__bmp_ 00265 44 8b c1 mov r8d, ecx 00268 45 0f af c5 imul r8d, r13d 0026c eb 18 jmp SHORT $LN375@stbi__bmp_ $LN186@stbi__bmp_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0026e b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00273 99 cdq 00274 f7 f9 idiv ecx ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00276 44 3b e8 cmp r13d, eax 00279 0f 8f 0f 10 00 00 jg $LN355@stbi__bmp_ 0027f 45 8b c5 mov r8d, r13d 00282 44 0f af c1 imul r8d, ecx $LN375@stbi__bmp_: ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00286 45 85 c9 test r9d, r9d 00289 74 12 je SHORT $LN364@stbi__bmp_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0028b b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00290 99 cdq 00291 41 f7 f9 idiv r9d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00294 44 3b c0 cmp r8d, eax 00297 0f 8f f1 0f 00 00 jg $LN355@stbi__bmp_ $LN364@stbi__bmp_: 0029d 41 0f af c9 imul ecx, r9d ; 509 : return stbi__malloc(a * b * c + add); 002a1 41 0f af cd imul ecx, r13d 002a5 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 002a8 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 002ae 48 89 84 24 90 00 00 00 mov QWORD PTR out$1$[rsp], rax 002b6 48 8b f0 mov rsi, rax ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 002b9 48 85 c0 test rax, rax 002bc 0f 84 cc 0f 00 00 je $LN355@stbi__bmp_ ; 5125 : if (info.bpp < 16) { 002c2 83 ff 10 cmp edi, 16 002c5 0f 8d ee 05 00 00 jge $LN54@stbi__bmp_ ; 5126 : int z = 0; 002cb 33 d2 xor edx, edx 002cd 8b fa mov edi, edx ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } 002cf 45 85 e4 test r12d, r12d 002d2 0f 84 b9 05 00 00 je $LN57@stbi__bmp_ 002d8 41 81 fc 00 01 00 00 cmp r12d, 256 ; 00000100H 002df 0f 8f ac 05 00 00 jg $LN57@stbi__bmp_ ; 5128 : for (i = 0; i < psize; ++i) { 002e5 44 89 ac 24 48 05 00 00 mov DWORD PTR target$4$[rsp], r13d 002ed 45 85 e4 test r12d, r12d 002f0 0f 8e 5b 01 00 00 jle $LN341@stbi__bmp_ ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) 002f6 44 8b 74 24 30 mov r14d, DWORD PTR info$2$[rsp] 002fb 48 8d 6b 30 lea rbp, QWORD PTR [rbx+48] 002ff 49 63 f4 movsxd rsi, r12d 00302 0f 1f 40 00 66 66 0f 1f 84 00 00 00 00 00 npad 14 $LL4@stbi__bmp_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00310 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00317 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0031e 73 0f jae SHORT $LN239@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00320 0f b6 08 movzx ecx, BYTE PTR [rax] 00323 48 ff c0 inc rax 00326 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0032d eb 29 jmp SHORT $LN238@stbi__bmp_ $LN239@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 0032f 39 7b 30 cmp DWORD PTR [rbx+48], edi 00332 48 8d 6b 30 lea rbp, QWORD PTR [rbx+48] 00336 74 1e je SHORT $LN240@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00338 48 8b cb mov rcx, rbx 0033b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00340 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00347 0f b6 08 movzx ecx, BYTE PTR [rax] 0034a 48 ff c0 inc rax 0034d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00354 eb 02 jmp SHORT $LN238@stbi__bmp_ $LN240@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00356 32 c9 xor cl, cl $LN238@stbi__bmp_: ; 5129 : pal[i][2] = stbi__get8(s); 00358 4c 8b ed mov r13, rbp 0035b 42 88 8c bc e2 00 00 00 mov BYTE PTR pal$[rsp+r15*4+2], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00363 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0036a 73 0f jae SHORT $LN235@stbi__bmp_ ; 1078 : return *s->img_buffer++; 0036c 0f b6 08 movzx ecx, BYTE PTR [rax] 0036f 48 ff c0 inc rax 00372 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00379 eb 25 jmp SHORT $LN234@stbi__bmp_ $LN235@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 0037b 39 7d 00 cmp DWORD PTR [rbp], edi 0037e 74 1e je SHORT $LN236@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00380 48 8b cb mov rcx, rbx 00383 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00388 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0038f 0f b6 08 movzx ecx, BYTE PTR [rax] 00392 48 ff c0 inc rax 00395 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0039c eb 02 jmp SHORT $LN234@stbi__bmp_ $LN236@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 0039e 32 c9 xor cl, cl $LN234@stbi__bmp_: ; 5130 : pal[i][1] = stbi__get8(s); 003a0 42 88 8c bc e1 00 00 00 mov BYTE PTR pal$[rsp+r15*4+1], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 003a8 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 003af 73 13 jae SHORT $LN231@stbi__bmp_ ; 1078 : return *s->img_buffer++; 003b1 0f b6 08 movzx ecx, BYTE PTR [rax] 003b4 48 8d 6b 30 lea rbp, QWORD PTR [rbx+48] 003b8 48 ff c0 inc rax 003bb 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003c2 eb 25 jmp SHORT $LN230@stbi__bmp_ $LN231@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 003c4 39 7d 00 cmp DWORD PTR [rbp], edi 003c7 74 1e je SHORT $LN232@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 003c9 48 8b cb mov rcx, rbx 003cc e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003d1 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 003d8 0f b6 08 movzx ecx, BYTE PTR [rax] 003db 48 ff c0 inc rax 003de 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003e5 eb 02 jmp SHORT $LN230@stbi__bmp_ $LN232@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 003e7 32 c9 xor cl, cl $LN230@stbi__bmp_: ; 5131 : pal[i][0] = stbi__get8(s); 003e9 42 88 8c bc e0 00 00 00 mov BYTE PTR pal$[rsp+r15*4], cl ; 5132 : if (info.hsz != 12) stbi__get8(s); 003f1 41 83 fe 0c cmp r14d, 12 003f5 74 2a je SHORT $LN252@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 003f7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 003fe 73 0c jae SHORT $LN251@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00400 48 ff c0 inc rax 00403 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0040a eb 15 jmp SHORT $LN252@stbi__bmp_ $LN251@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 0040c 41 39 7d 00 cmp DWORD PTR [r13], edi 00410 74 0f je SHORT $LN252@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00412 48 8b cb mov rcx, rbx 00415 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0041a 48 ff 83 c0 00 00 00 inc QWORD PTR [rbx+192] $LN252@stbi__bmp_: ; 5133 : pal[i][3] = 255; 00421 42 c6 84 bc e3 00 00 00 ff mov BYTE PTR pal$[rsp+r15*4+3], 255 ; 000000ffH 0042a 49 ff c7 inc r15 0042d 4c 3b fe cmp r15, rsi 00430 0f 8c da fe ff ff jl $LL4@stbi__bmp_ 00436 48 8b b4 24 90 00 00 00 mov rsi, QWORD PTR out$1$[rsp] 0043e 33 d2 xor edx, edx 00440 44 8b 74 24 3c mov r14d, DWORD PTR n$1$[rsp] 00445 8b 6c 24 30 mov ebp, DWORD PTR info$2$[rsp] 00449 44 8b ac 24 48 05 00 00 mov r13d, DWORD PTR target$4$[rsp] $LN341@stbi__bmp_: ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); 00451 83 fd 0c cmp ebp, 12 00454 8b c2 mov eax, edx 00456 0f 95 c0 setne al 00459 83 c0 03 add eax, 3 0045c 41 0f af c4 imul eax, r12d 00460 44 2b f0 sub r14d, eax 00463 44 2b 74 24 34 sub r14d, DWORD PTR info$5$[rsp] 00468 44 2b f5 sub r14d, ebp ; 1107 : if (n == 0) return; // already there! 0046b 74 55 je SHORT $LN224@stbi__bmp_ ; 1108 : if (n < 0) { 0046d 45 85 f6 test r14d, r14d 00470 79 10 jns SHORT $LN226@stbi__bmp_ ; 1109 : s->img_buffer = s->img_buffer_end; 00472 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00479 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 1110 : return; 00480 eb 40 jmp SHORT $LN224@stbi__bmp_ $LN226@stbi__bmp_: ; 1111 : } ; 1112 : if (s->io.read) { 00482 48 39 7b 10 cmp QWORD PTR [rbx+16], rdi 00486 74 30 je SHORT $LN357@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00488 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 0048e 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 00494 41 3b ce cmp ecx, r14d 00497 7d 1f jge SHORT $LN357@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 00499 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 004a0 44 2b f1 sub r14d, ecx 004a3 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 004a7 41 8b d6 mov edx, r14d 004aa 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004b1 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 004b4 33 d2 xor edx, edx 004b6 eb 0a jmp SHORT $LN224@stbi__bmp_ $LN357@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 004b8 49 63 c6 movsxd rax, r14d 004bb 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN224@stbi__bmp_: ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; 004c2 44 8b 64 24 40 mov r12d, DWORD PTR info$3$[rsp] 004c7 41 83 fc 01 cmp r12d, 1 004cb 75 0d jne SHORT $LN59@stbi__bmp_ 004cd 44 8b 3b mov r15d, DWORD PTR [rbx] 004d0 41 83 c7 07 add r15d, 7 004d4 41 c1 ef 03 shr r15d, 3 004d8 eb 1e jmp SHORT $LN64@stbi__bmp_ $LN59@stbi__bmp_: ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; 004da 41 83 fc 04 cmp r12d, 4 004de 75 0b jne SHORT $LN61@stbi__bmp_ 004e0 44 8b 3b mov r15d, DWORD PTR [rbx] 004e3 41 ff c7 inc r15d 004e6 41 d1 ef shr r15d, 1 004e9 eb 0d jmp SHORT $LN64@stbi__bmp_ $LN61@stbi__bmp_: ; 5138 : else if (info.bpp == 8) width = s->img_x; 004eb 41 83 fc 08 cmp r12d, 8 004ef 0f 85 74 03 00 00 jne $LN63@stbi__bmp_ 004f5 44 8b 3b mov r15d, DWORD PTR [rbx] $LN64@stbi__bmp_: ; 5140 : pad = (-width) & 3; 004f8 8b 43 04 mov eax, DWORD PTR [rbx+4] 004fb 41 f7 df neg r15d 004fe 41 83 e7 03 and r15d, 3 00502 44 89 7c 24 30 mov DWORD PTR pad$1$[rsp], r15d ; 5141 : if (info.bpp == 1) { 00507 41 83 fc 01 cmp r12d, 1 0050b 0f 85 7c 01 00 00 jne $LN65@stbi__bmp_ ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { 00511 44 8b e2 mov r12d, edx 00514 85 c0 test eax, eax 00516 0f 8e 41 03 00 00 jle $LN12@stbi__bmp_ 0051c 48 8b fa mov rdi, rdx 0051f 90 npad 1 $LL7@stbi__bmp_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00520 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] ; 5143 : int bit_offset = 7, v = stbi__get8(s); 00527 bd 07 00 00 00 mov ebp, 7 ; 1077 : if (s->img_buffer < s->img_buffer_end) 0052c 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00533 73 0f jae SHORT $LN217@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00535 0f b6 08 movzx ecx, BYTE PTR [rax] 00538 48 ff c0 inc rax 0053b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00542 eb 26 jmp SHORT $LN216@stbi__bmp_ $LN217@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00544 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00548 74 1e je SHORT $LN218@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 0054a 48 8b cb mov rcx, rbx 0054d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00552 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00559 0f b6 08 movzx ecx, BYTE PTR [rax] 0055c 48 ff c0 inc rax 0055f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00566 eb 02 jmp SHORT $LN216@stbi__bmp_ $LN218@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00568 32 c9 xor cl, cl $LN216@stbi__bmp_: ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { 0056a 33 c0 xor eax, eax 0056c 0f b6 d1 movzx edx, cl 0056f 44 8b f0 mov r14d, eax 00572 39 03 cmp DWORD PTR [rbx], eax 00574 0f 8e b5 00 00 00 jle $LN377@stbi__bmp_ 0057a 66 0f 1f 44 00 00 npad 6 $LL10@stbi__bmp_: ; 5145 : int color = (v >> bit_offset) & 0x1; 00580 8b c2 mov eax, edx 00582 8b cd mov ecx, ebp 00584 d3 f8 sar eax, cl 00586 83 e0 01 and eax, 1 ; 5146 : out[z++] = pal[color][0]; 00589 48 8d 0c 85 00 00 00 00 lea rcx, QWORD PTR [rax*4] 00591 0f b6 84 0c e0 00 00 00 movzx eax, BYTE PTR pal$[rsp+rcx] 00599 88 04 37 mov BYTE PTR [rdi+rsi], al ; 5147 : out[z++] = pal[color][1]; 0059c 0f b6 84 0c e1 00 00 00 movzx eax, BYTE PTR pal$[rsp+rcx+1] 005a4 88 44 37 01 mov BYTE PTR [rdi+rsi+1], al ; 5148 : out[z++] = pal[color][2]; 005a8 0f b6 84 0c e2 00 00 00 movzx eax, BYTE PTR pal$[rsp+rcx+2] 005b0 88 44 37 02 mov BYTE PTR [rdi+rsi+2], al 005b4 48 83 c7 03 add rdi, 3 ; 5149 : if (target == 4) out[z++] = 255; 005b8 41 83 fd 04 cmp r13d, 4 005bc 75 07 jne SHORT $LN67@stbi__bmp_ 005be c6 04 37 ff mov BYTE PTR [rdi+rsi], 255 ; 000000ffH 005c2 48 ff c7 inc rdi $LN67@stbi__bmp_: ; 5150 : if (i + 1 == (int)s->img_x) break; 005c5 8b 0b mov ecx, DWORD PTR [rbx] 005c7 41 8d 46 01 lea eax, DWORD PTR [r14+1] 005cb 44 8b f0 mov r14d, eax 005ce 3b c1 cmp eax, ecx 005d0 74 5d je SHORT $LN377@stbi__bmp_ ; 5151 : if ((--bit_offset) < 0) { 005d2 83 ed 01 sub ebp, 1 005d5 79 4f jns SHORT $LN342@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 005d7 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] ; 5152 : bit_offset = 7; 005de bd 07 00 00 00 mov ebp, 7 ; 1077 : if (s->img_buffer < s->img_buffer_end) 005e3 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 005ea 73 0f jae SHORT $LN203@stbi__bmp_ ; 1078 : return *s->img_buffer++; 005ec 0f b6 10 movzx edx, BYTE PTR [rax] 005ef 48 ff c0 inc rax 005f2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 005f9 eb 28 jmp SHORT $LN202@stbi__bmp_ $LN203@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 005fb 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 005ff 74 20 je SHORT $LN204@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00601 48 8b cb mov rcx, rbx 00604 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00609 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00610 0f b6 10 movzx edx, BYTE PTR [rax] 00613 48 ff c0 inc rax 00616 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0061d 8b 0b mov ecx, DWORD PTR [rbx] 0061f eb 02 jmp SHORT $LN202@stbi__bmp_ $LN204@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00621 32 d2 xor dl, dl $LN202@stbi__bmp_: ; 5153 : v = stbi__get8(s); 00623 0f b6 d2 movzx edx, dl $LN342@stbi__bmp_: ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { 00626 44 3b f1 cmp r14d, ecx 00629 0f 8c 51 ff ff ff jl $LL10@stbi__bmp_ $LN377@stbi__bmp_: ; 1107 : if (n == 0) return; // already there! 0062f 45 85 ff test r15d, r15d 00632 74 3e je SHORT $LN5@stbi__bmp_ ; 1111 : } ; 1112 : if (s->io.read) { 00634 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00639 74 2d je SHORT $LN361@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 0063b 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 00641 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 00647 41 3b cf cmp ecx, r15d 0064a 7d 1c jge SHORT $LN361@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 0064c 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00653 41 8b d7 mov edx, r15d 00656 2b d1 sub edx, ecx 00658 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0065f 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 00663 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 00666 eb 0a jmp SHORT $LN5@stbi__bmp_ $LN361@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00668 41 8b c7 mov eax, r15d 0066b 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN5@stbi__bmp_: ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { 00672 8b 43 04 mov eax, DWORD PTR [rbx+4] 00675 41 ff c4 inc r12d 00678 44 3b e0 cmp r12d, eax 0067b 0f 8c 9f fe ff ff jl $LL7@stbi__bmp_ ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } 00681 8b ac 24 48 05 00 00 mov ebp, DWORD PTR target$4$[rsp] 00688 e9 c7 0a 00 00 jmp $LN18@stbi__bmp_ $LN65@stbi__bmp_: ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { 0068d 44 8b f2 mov r14d, edx 00690 85 c0 test eax, eax 00692 0f 8e c5 01 00 00 jle $LN12@stbi__bmp_ 00698 0f 1f 84 00 00 00 00 00 npad 8 $LL13@stbi__bmp_: ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { 006a0 83 3b 00 cmp DWORD PTR [rbx], 0 006a3 8b ea mov ebp, edx 006a5 0f 8e 5b 01 00 00 jle $LN318@stbi__bmp_ 006ab 45 33 ff xor r15d, r15d 006ae 66 90 npad 2 $LL16@stbi__bmp_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 006b0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006b7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 006be 73 0f jae SHORT $LN122@stbi__bmp_ ; 1078 : return *s->img_buffer++; 006c0 0f b6 08 movzx ecx, BYTE PTR [rax] 006c3 48 ff c0 inc rax 006c6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 006cd eb 26 jmp SHORT $LN121@stbi__bmp_ $LN122@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 006cf 44 39 7b 30 cmp DWORD PTR [rbx+48], r15d 006d3 74 1e je SHORT $LN123@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 006d5 48 8b cb mov rcx, rbx 006d8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 006dd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006e4 0f b6 08 movzx ecx, BYTE PTR [rax] 006e7 48 ff c0 inc rax 006ea 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 006f1 eb 02 jmp SHORT $LN121@stbi__bmp_ $LN123@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 006f3 32 c9 xor cl, cl $LN121@stbi__bmp_: ; 5162 : int v = stbi__get8(s), v2 = 0; 006f5 0f b6 c1 movzx eax, cl 006f8 45 8b c7 mov r8d, r15d ; 5163 : if (info.bpp == 4) { 006fb 41 83 fc 04 cmp r12d, 4 006ff 75 0a jne SHORT $LN70@stbi__bmp_ ; 5164 : v2 = v & 15; 00701 44 8b c0 mov r8d, eax 00704 41 83 e0 0f and r8d, 15 ; 5165 : v >>= 4; 00708 c1 e8 04 shr eax, 4 $LN70@stbi__bmp_: ; 5166 : } ; 5167 : out[z++] = pal[v][0]; 0070b 48 63 cf movsxd rcx, edi 0070e 48 8d 14 85 00 00 00 00 lea rdx, QWORD PTR [rax*4] 00716 0f b6 84 14 e0 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx] 0071e ff c7 inc edi 00720 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5168 : out[z++] = pal[v][1]; 00723 0f b6 84 14 e1 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx+1] 0072b 48 63 cf movsxd rcx, edi 0072e ff c7 inc edi 00730 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5169 : out[z++] = pal[v][2]; 00733 0f b6 84 14 e2 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx+2] 0073b 48 63 cf movsxd rcx, edi 0073e ff c7 inc edi 00740 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5170 : if (target == 4) out[z++] = 255; 00743 41 83 fd 04 cmp r13d, 4 00747 75 09 jne SHORT $LN71@stbi__bmp_ 00749 48 63 c7 movsxd rax, edi 0074c ff c7 inc edi 0074e c6 04 30 ff mov BYTE PTR [rax+rsi], 255 ; 000000ffH $LN71@stbi__bmp_: ; 5171 : if (i + 1 == (int)s->img_x) break; 00752 8d 45 01 lea eax, DWORD PTR [rbp+1] 00755 3b 03 cmp eax, DWORD PTR [rbx] 00757 0f 84 a4 00 00 00 je $LN378@stbi__bmp_ ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; 0075d 41 83 fc 08 cmp r12d, 8 00761 75 49 jne SHORT $LN97@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00763 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0076a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00771 73 0f jae SHORT $LN199@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00773 0f b6 08 movzx ecx, BYTE PTR [rax] 00776 48 ff c0 inc rax 00779 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00780 eb 26 jmp SHORT $LN198@stbi__bmp_ $LN199@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00782 44 39 7b 30 cmp DWORD PTR [rbx+48], r15d 00786 74 1e je SHORT $LN200@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00788 48 8b cb mov rcx, rbx 0078b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00790 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00797 0f b6 08 movzx ecx, BYTE PTR [rax] 0079a 48 ff c0 inc rax 0079d 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 007a4 eb 02 jmp SHORT $LN198@stbi__bmp_ $LN200@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 007a6 32 c9 xor cl, cl $LN198@stbi__bmp_: ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; 007a8 44 0f b6 c1 movzx r8d, cl $LN97@stbi__bmp_: ; 5173 : out[z++] = pal[v][0]; 007ac 48 63 cf movsxd rcx, edi 007af ff c7 inc edi 007b1 41 8b c0 mov eax, r8d 007b4 48 8d 14 85 00 00 00 00 lea rdx, QWORD PTR [rax*4] 007bc 0f b6 84 14 e0 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx] 007c4 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5174 : out[z++] = pal[v][1]; 007c7 0f b6 84 14 e1 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx+1] 007cf 48 63 cf movsxd rcx, edi 007d2 ff c7 inc edi 007d4 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5175 : out[z++] = pal[v][2]; 007d7 0f b6 84 14 e2 00 00 00 movzx eax, BYTE PTR pal$[rsp+rdx+2] 007df 48 63 cf movsxd rcx, edi 007e2 ff c7 inc edi 007e4 88 04 31 mov BYTE PTR [rcx+rsi], al ; 5176 : if (target == 4) out[z++] = 255; 007e7 41 83 fd 04 cmp r13d, 4 007eb 75 09 jne SHORT $LN14@stbi__bmp_ 007ed 48 63 c7 movsxd rax, edi 007f0 ff c7 inc edi 007f2 c6 04 30 ff mov BYTE PTR [rax+rsi], 255 ; 000000ffH $LN14@stbi__bmp_: ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { 007f6 83 c5 02 add ebp, 2 007f9 3b 2b cmp ebp, DWORD PTR [rbx] 007fb 0f 8c af fe ff ff jl $LL16@stbi__bmp_ $LN378@stbi__bmp_: 00801 44 8b 7c 24 30 mov r15d, DWORD PTR pad$1$[rsp] $LN318@stbi__bmp_: ; 1107 : if (n == 0) return; // already there! 00806 45 85 ff test r15d, r15d 00809 74 3e je SHORT $LN11@stbi__bmp_ ; 1111 : } ; 1112 : if (s->io.read) { 0080b 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00810 74 2d je SHORT $LN358@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00812 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 00818 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 0081e 41 3b cf cmp ecx, r15d 00821 7d 1c jge SHORT $LN358@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 00823 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0082a 41 8b d7 mov edx, r15d 0082d 2b d1 sub edx, ecx 0082f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00836 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0083a ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 0083d eb 0a jmp SHORT $LN11@stbi__bmp_ $LN358@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0083f 41 8b c7 mov eax, r15d 00842 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN11@stbi__bmp_: ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { 00849 8b 43 04 mov eax, DWORD PTR [rbx+4] 0084c 41 ff c6 inc r14d 0084f ba 00 00 00 00 mov edx, 0 00854 44 3b f0 cmp r14d, eax 00857 0f 8c 43 fe ff ff jl $LL13@stbi__bmp_ $LN12@stbi__bmp_: ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } 0085d 8b ac 24 48 05 00 00 mov ebp, DWORD PTR target$4$[rsp] 00864 e9 eb 08 00 00 jmp $LN18@stbi__bmp_ $LN63@stbi__bmp_: ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } 00869 48 8b ce mov rcx, rsi 0086c ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 00872 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00878 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00881 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00885 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07JNJHIMGH@bad?5bpp@ ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } 0088c e9 4f 0a 00 00 jmp $LN528@stbi__bmp_ $LN57@stbi__bmp_: ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } 00891 48 8b ce mov rcx, rsi 00894 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 0089a 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 008a0 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 008a9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 008ad 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07MALOAKCI@invalid@ ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } 008b4 e9 27 0a 00 00 jmp $LN528@stbi__bmp_ $LN54@stbi__bmp_: ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); 008b9 44 2b 74 24 34 sub r14d, DWORD PTR info$5$[rsp] 008be 45 33 d2 xor r10d, r10d 008c1 44 89 54 24 60 mov DWORD PTR rshift$1$[rsp], r10d 008c6 41 8b d2 mov edx, r10d 008c9 89 54 24 30 mov DWORD PTR ashift$1$[rsp], edx 008cd 45 8b da mov r11d, r10d 008d0 44 89 54 24 44 mov DWORD PTR gshift$1$[rsp], r10d 008d5 45 8b c2 mov r8d, r10d 008d8 44 89 54 24 3c mov DWORD PTR bshift$1$[rsp], r10d 008dd 45 8b ea mov r13d, r10d 008e0 41 8b fa mov edi, r10d 008e3 45 8b e2 mov r12d, r10d 008e6 44 2b f5 sub r14d, ebp ; 1107 : if (n == 0) return; // already there! 008e9 74 5f je SHORT $LN242@stbi__bmp_ ; 1108 : if (n < 0) { 008eb 45 85 f6 test r14d, r14d 008ee 79 10 jns SHORT $LN244@stbi__bmp_ ; 1109 : s->img_buffer = s->img_buffer_end; 008f0 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 008f7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 1110 : return; 008fe eb 4a jmp SHORT $LN242@stbi__bmp_ $LN244@stbi__bmp_: ; 1111 : } ; 1112 : if (s->io.read) { 00900 48 39 53 10 cmp QWORD PTR [rbx+16], rdx 00904 74 3a je SHORT $LN359@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00906 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 0090c 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 00912 41 3b ce cmp ecx, r14d 00915 7d 29 jge SHORT $LN359@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 00917 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0091e 44 2b f1 sub r14d, ecx 00921 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 00925 41 8b d6 mov edx, r14d 00928 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0092f ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 00932 41 8b d4 mov edx, r12d 00935 45 8b dc mov r11d, r12d 00938 45 8b c4 mov r8d, r12d 0093b 45 33 d2 xor r10d, r10d 0093e eb 0a jmp SHORT $LN242@stbi__bmp_ $LN359@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00940 49 63 c6 movsxd rax, r14d 00943 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN242@stbi__bmp_: ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; 0094a 8b 4c 24 40 mov ecx, DWORD PTR info$3$[rsp] 0094e 83 f9 18 cmp ecx, 24 00951 75 08 jne SHORT $LN74@stbi__bmp_ 00953 8b 03 mov eax, DWORD PTR [rbx] 00955 44 8d 0c 40 lea r9d, DWORD PTR [rax+rax*2] 00959 eb 10 jmp SHORT $LN77@stbi__bmp_ $LN74@stbi__bmp_: ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; 0095b 83 f9 10 cmp ecx, 16 0095e 75 08 jne SHORT $LN76@stbi__bmp_ 00960 44 8b 0b mov r9d, DWORD PTR [rbx] 00963 45 03 c9 add r9d, r9d 00966 eb 03 jmp SHORT $LN77@stbi__bmp_ $LN76@stbi__bmp_: ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; 00968 45 8b ca mov r9d, r10d $LN77@stbi__bmp_: ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { 0096b 8b ac 24 48 05 00 00 mov ebp, DWORD PTR target$4$[rsp] 00972 41 f7 d9 neg r9d 00975 41 83 e1 03 and r9d, 3 00979 44 89 4c 24 34 mov DWORD PTR pad$2$[rsp], r9d 0097e 83 f9 18 cmp ecx, 24 00981 75 11 jne SHORT $LN78@stbi__bmp_ ; 5192 : easy = 1; 00983 48 c7 44 24 58 01 00 00 00 mov QWORD PTR $T22[rsp], 1 ; 5193 : } 0098c 45 8b f4 mov r14d, r12d 0098f e9 97 03 00 00 jmp $LN85@stbi__bmp_ $LN78@stbi__bmp_: ; 5194 : else if (info.bpp == 32) { 00994 83 f9 20 cmp ecx, 32 ; 00000020H 00997 4c 89 54 24 58 mov QWORD PTR $T22[rsp], r10 0099c 8b 4c 24 50 mov ecx, DWORD PTR mb$1$[rsp] 009a0 8b c5 mov eax, ebp 009a2 75 4f jne SHORT $LN362@stbi__bmp_ ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) 009a4 4c 89 54 24 58 mov QWORD PTR $T22[rsp], r10 009a9 81 f9 ff 00 00 00 cmp ecx, 255 ; 000000ffH 009af 75 42 jne SHORT $LN362@stbi__bmp_ 009b1 81 7c 24 4c 00 ff 00 00 cmp DWORD PTR mg$1$[rsp], 65280 ; 0000ff00H 009b9 4c 89 54 24 58 mov QWORD PTR $T22[rsp], r10 009be 75 33 jne SHORT $LN362@stbi__bmp_ 009c0 81 7c 24 48 00 00 ff 00 cmp DWORD PTR mr$1$[rsp], 16711680 ; 00ff0000H 009c8 4c 89 54 24 58 mov QWORD PTR $T22[rsp], r10 009cd 75 24 jne SHORT $LN362@stbi__bmp_ 009cf 4c 89 54 24 58 mov QWORD PTR $T22[rsp], r10 009d4 44 8b 54 24 64 mov r10d, DWORD PTR ma$1$[rsp] 009d9 41 81 fa 00 00 00 ff cmp r10d, -16777216 ; ff000000H 009e0 75 3c jne SHORT $LN379@stbi__bmp_ ; 5196 : easy = 2; 009e2 48 c7 44 24 58 02 00 00 00 mov QWORD PTR $T22[rsp], 2 009eb 45 8b f4 mov r14d, r12d 009ee e9 38 03 00 00 jmp $LN85@stbi__bmp_ $LN362@stbi__bmp_: ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } 009f3 8b 7c 24 48 mov edi, DWORD PTR mr$1$[rsp] 009f7 8b e8 mov ebp, eax 009f9 85 ff test edi, edi 009fb 0f 84 68 08 00 00 je $LN86@stbi__bmp_ 00a01 44 8b 7c 24 4c mov r15d, DWORD PTR mg$1$[rsp] 00a06 45 85 ff test r15d, r15d 00a09 0f 84 5a 08 00 00 je $LN86@stbi__bmp_ 00a0f 85 c9 test ecx, ecx 00a11 0f 84 52 08 00 00 je $LN86@stbi__bmp_ ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) 00a17 44 8b 54 24 64 mov r10d, DWORD PTR ma$1$[rsp] 00a1c eb 09 jmp SHORT $LN372@stbi__bmp_ $LN379@stbi__bmp_: 00a1e 8b 7c 24 48 mov edi, DWORD PTR mr$1$[rsp] 00a22 44 8b 7c 24 4c mov r15d, DWORD PTR mg$1$[rsp] $LN372@stbi__bmp_: ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); 00a27 8b cf mov ecx, edi ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } 00a29 81 ff 00 00 01 00 cmp edi, 65536 ; 00010000H 00a2f 72 03 jb SHORT $LN266@stbi__bmp_ 00a31 c1 e9 10 shr ecx, 16 $LN266@stbi__bmp_: ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } 00a34 81 ff 00 00 01 00 cmp edi, 65536 ; 00010000H 00a3a 41 b9 10 00 00 00 mov r9d, 16 00a40 41 8b d1 mov edx, r9d 00a43 41 0f 42 d4 cmovb edx, r12d 00a47 81 f9 00 01 00 00 cmp ecx, 256 ; 00000100H 00a4d 72 06 jb SHORT $LN267@stbi__bmp_ 00a4f 83 c2 08 add edx, 8 00a52 c1 e9 08 shr ecx, 8 $LN267@stbi__bmp_: ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } 00a55 41 3b c9 cmp ecx, r9d 00a58 8d 42 04 lea eax, DWORD PTR [rdx+4] 00a5b 44 8b c1 mov r8d, ecx 00a5e 0f 42 c2 cmovb eax, edx 00a61 41 c1 e8 04 shr r8d, 4 00a65 41 3b c9 cmp ecx, r9d 00a68 44 0f 42 c1 cmovb r8d, ecx ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00a6c 8d 50 02 lea edx, DWORD PTR [rax+2] 00a6f 41 83 f8 04 cmp r8d, 4 00a73 41 8b c8 mov ecx, r8d 00a76 0f 42 d0 cmovb edx, eax 00a79 c1 e9 02 shr ecx, 2 00a7c 41 83 f8 04 cmp r8d, 4 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00a80 8b c7 mov eax, edi ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00a82 41 0f 42 c8 cmovb ecx, r8d ; 4898 : return n; 00a86 83 f9 02 cmp ecx, 2 00a89 44 8d 5a 01 lea r11d, DWORD PTR [rdx+1] ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00a8d 8b cf mov ecx, edi ; 4898 : return n; 00a8f 44 0f 42 da cmovb r11d, edx ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00a93 25 55 55 55 55 and eax, 1431655765 ; 55555555H 00a98 d1 e9 shr ecx, 1 ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); 00a9a 41 83 c3 f9 add r11d, -7 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00a9e 81 e1 55 55 55 55 and ecx, 1431655765 ; 55555555H ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); 00aa4 44 89 5c 24 60 mov DWORD PTR rshift$1$[rsp], r11d ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00aa9 03 c8 add ecx, eax ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 00aab 8b c1 mov eax, ecx 00aad 81 e1 33 33 33 33 and ecx, 858993459 ; 33333333H 00ab3 c1 e8 02 shr eax, 2 00ab6 25 33 33 33 33 and eax, 858993459 ; 33333333H 00abb 03 c1 add eax, ecx ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 00abd 8b c8 mov ecx, eax 00abf c1 e9 04 shr ecx, 4 00ac2 03 c8 add ecx, eax 00ac4 81 e1 0f 0f 0f 0f and ecx, 252645135 ; 0f0f0f0fH ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits 00aca 8b c1 mov eax, ecx 00acc c1 e8 08 shr eax, 8 00acf 03 c8 add ecx, eax ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits 00ad1 8b c1 mov eax, ecx 00ad3 c1 e8 10 shr eax, 16 00ad6 03 c1 add eax, ecx ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); 00ad8 41 8b cf mov ecx, r15d ; 4908 : return a & 0xff; 00adb 44 0f b6 e8 movzx r13d, al ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } 00adf 41 81 ff 00 00 01 00 cmp r15d, 65536 ; 00010000H 00ae6 72 03 jb SHORT $LN276@stbi__bmp_ 00ae8 c1 e9 10 shr ecx, 16 $LN276@stbi__bmp_: ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } 00aeb 41 81 ff 00 00 01 00 cmp r15d, 65536 ; 00010000H 00af2 41 8b d1 mov edx, r9d 00af5 41 0f 42 d4 cmovb edx, r12d 00af9 81 f9 00 01 00 00 cmp ecx, 256 ; 00000100H 00aff 72 06 jb SHORT $LN277@stbi__bmp_ 00b01 83 c2 08 add edx, 8 00b04 c1 e9 08 shr ecx, 8 $LN277@stbi__bmp_: ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); 00b07 8b 7c 24 50 mov edi, DWORD PTR mb$1$[rsp] ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } 00b0b 8d 42 04 lea eax, DWORD PTR [rdx+4] 00b0e 41 3b c9 cmp ecx, r9d 00b11 44 8b c1 mov r8d, ecx 00b14 0f 42 c2 cmovb eax, edx 00b17 41 c1 e8 04 shr r8d, 4 00b1b 41 3b c9 cmp ecx, r9d 00b1e 44 0f 42 c1 cmovb r8d, ecx ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00b22 8d 50 02 lea edx, DWORD PTR [rax+2] 00b25 41 83 f8 04 cmp r8d, 4 00b29 41 8b c8 mov ecx, r8d 00b2c 0f 42 d0 cmovb edx, eax 00b2f c1 e9 02 shr ecx, 2 00b32 41 83 f8 04 cmp r8d, 4 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00b36 41 8b c7 mov eax, r15d ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00b39 41 0f 42 c8 cmovb ecx, r8d ; 4898 : return n; 00b3d 83 f9 02 cmp ecx, 2 00b40 44 8d 72 01 lea r14d, DWORD PTR [rdx+1] ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00b44 41 8b cf mov ecx, r15d ; 4898 : return n; 00b47 44 0f 42 f2 cmovb r14d, edx ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00b4b 25 55 55 55 55 and eax, 1431655765 ; 55555555H 00b50 d1 e9 shr ecx, 1 ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); 00b52 41 83 c6 f9 add r14d, -7 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00b56 81 e1 55 55 55 55 and ecx, 1431655765 ; 55555555H ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); 00b5c 44 89 74 24 44 mov DWORD PTR gshift$1$[rsp], r14d ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00b61 03 c8 add ecx, eax ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 00b63 8b c1 mov eax, ecx 00b65 81 e1 33 33 33 33 and ecx, 858993459 ; 33333333H 00b6b c1 e8 02 shr eax, 2 00b6e 25 33 33 33 33 and eax, 858993459 ; 33333333H 00b73 03 c1 add eax, ecx ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 00b75 8b c8 mov ecx, eax 00b77 c1 e9 04 shr ecx, 4 00b7a 03 c8 add ecx, eax 00b7c 81 e1 0f 0f 0f 0f and ecx, 252645135 ; 0f0f0f0fH ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits 00b82 8b c1 mov eax, ecx 00b84 c1 e8 08 shr eax, 8 00b87 03 c8 add ecx, eax ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits 00b89 8b c1 mov eax, ecx 00b8b c1 e8 10 shr eax, 16 00b8e 03 c1 add eax, ecx ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); 00b90 8b cf mov ecx, edi ; 4908 : return a & 0xff; 00b92 44 0f b6 e0 movzx r12d, al ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } 00b96 81 ff 00 00 01 00 cmp edi, 65536 ; 00010000H 00b9c 72 03 jb SHORT $LN286@stbi__bmp_ 00b9e c1 e9 10 shr ecx, 16 $LN286@stbi__bmp_: ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } 00ba1 81 ff 00 00 01 00 cmp edi, 65536 ; 00010000H 00ba7 41 8b d1 mov edx, r9d 00baa b8 00 00 00 00 mov eax, 0 00baf 0f 42 d0 cmovb edx, eax 00bb2 81 f9 00 01 00 00 cmp ecx, 256 ; 00000100H 00bb8 72 06 jb SHORT $LN287@stbi__bmp_ 00bba 83 c2 08 add edx, 8 00bbd c1 e9 08 shr ecx, 8 $LN287@stbi__bmp_: ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } 00bc0 41 3b c9 cmp ecx, r9d 00bc3 8d 42 04 lea eax, DWORD PTR [rdx+4] 00bc6 44 8b c1 mov r8d, ecx 00bc9 0f 42 c2 cmovb eax, edx 00bcc 41 c1 e8 04 shr r8d, 4 00bd0 41 3b c9 cmp ecx, r9d 00bd3 44 0f 42 c1 cmovb r8d, ecx ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00bd7 8d 50 02 lea edx, DWORD PTR [rax+2] 00bda 41 83 f8 04 cmp r8d, 4 00bde 41 8b c8 mov ecx, r8d 00be1 0f 42 d0 cmovb edx, eax 00be4 c1 e9 02 shr ecx, 2 00be7 41 83 f8 04 cmp r8d, 4 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00beb 8b c7 mov eax, edi ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00bed 41 0f 42 c8 cmovb ecx, r8d ; 4898 : return n; 00bf1 83 f9 02 cmp ecx, 2 00bf4 44 8d 42 01 lea r8d, DWORD PTR [rdx+1] ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00bf8 8b cf mov ecx, edi ; 4898 : return n; 00bfa 44 0f 42 c2 cmovb r8d, edx ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00bfe 25 55 55 55 55 and eax, 1431655765 ; 55555555H 00c03 d1 e9 shr ecx, 1 ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); 00c05 41 83 c0 f9 add r8d, -7 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00c09 81 e1 55 55 55 55 and ecx, 1431655765 ; 55555555H ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); 00c0f 44 89 44 24 3c mov DWORD PTR bshift$1$[rsp], r8d ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00c14 03 c8 add ecx, eax ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 00c16 8b c1 mov eax, ecx 00c18 81 e1 33 33 33 33 and ecx, 858993459 ; 33333333H 00c1e c1 e8 02 shr eax, 2 00c21 25 33 33 33 33 and eax, 858993459 ; 33333333H 00c26 03 c1 add eax, ecx ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 00c28 8b c8 mov ecx, eax 00c2a c1 e9 04 shr ecx, 4 00c2d 03 c8 add ecx, eax 00c2f 81 e1 0f 0f 0f 0f and ecx, 252645135 ; 0f0f0f0fH ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits 00c35 8b c1 mov eax, ecx 00c37 c1 e8 08 shr eax, 8 00c3a 03 c8 add ecx, eax ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits 00c3c 8b c1 mov eax, ecx 00c3e c1 e8 10 shr eax, 16 00c41 03 c1 add eax, ecx ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); 00c43 41 8b ca mov ecx, r10d ; 4908 : return a & 0xff; 00c46 44 0f b6 f8 movzx r15d, al ; 4892 : if (z == 0) return -1; 00c4a 45 85 d2 test r10d, r10d 00c4d 75 06 jne SHORT $LN295@stbi__bmp_ 00c4f 41 8d 52 ff lea edx, QWORD PTR [r10-1] 00c53 eb 5e jmp SHORT $LN294@stbi__bmp_ $LN295@stbi__bmp_: ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } 00c55 41 81 fa 00 00 01 00 cmp r10d, 65536 ; 00010000H 00c5c 72 0a jb SHORT $LN524@stbi__bmp_ 00c5e c1 e9 10 shr ecx, 16 ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } 00c61 41 81 fa 00 00 01 00 cmp r10d, 65536 ; 00010000H $LN524@stbi__bmp_: 00c68 b8 00 00 00 00 mov eax, 0 00c6d 44 0f 42 c8 cmovb r9d, eax 00c71 81 f9 00 01 00 00 cmp ecx, 256 ; 00000100H 00c77 72 07 jb SHORT $LN297@stbi__bmp_ 00c79 41 83 c1 08 add r9d, 8 00c7d c1 e9 08 shr ecx, 8 $LN297@stbi__bmp_: ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } 00c80 83 f9 10 cmp ecx, 16 00c83 41 8d 41 04 lea eax, DWORD PTR [r9+4] 00c87 8b d1 mov edx, ecx 00c89 41 0f 42 c1 cmovb eax, r9d 00c8d c1 ea 04 shr edx, 4 00c90 83 f9 10 cmp ecx, 16 00c93 0f 42 d1 cmovb edx, ecx ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } 00c96 83 fa 04 cmp edx, 4 00c99 8d 48 02 lea ecx, DWORD PTR [rax+2] 00c9c 0f 42 c8 cmovb ecx, eax 00c9f 8b c2 mov eax, edx 00ca1 c1 e8 02 shr eax, 2 00ca4 83 fa 04 cmp edx, 4 00ca7 0f 42 c2 cmovb eax, edx ; 4898 : return n; 00caa 8d 51 01 lea edx, DWORD PTR [rcx+1] 00cad 83 f8 02 cmp eax, 2 00cb0 0f 42 d1 cmovb edx, ecx $LN294@stbi__bmp_: ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00cb3 41 8b ca mov ecx, r10d ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); 00cb6 83 c2 f9 add edx, -7 ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00cb9 d1 e9 shr ecx, 1 00cbb 41 8b c2 mov eax, r10d 00cbe 25 55 55 55 55 and eax, 1431655765 ; 55555555H ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); 00cc3 89 54 24 30 mov DWORD PTR ashift$1$[rsp], edx ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 00cc7 81 e1 55 55 55 55 and ecx, 1431655765 ; 55555555H 00ccd 03 c8 add ecx, eax ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 00ccf 8b c1 mov eax, ecx 00cd1 81 e1 33 33 33 33 and ecx, 858993459 ; 33333333H 00cd7 c1 e8 02 shr eax, 2 00cda 25 33 33 33 33 and eax, 858993459 ; 33333333H 00cdf 03 c1 add eax, ecx ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits 00ce1 8b c8 mov ecx, eax 00ce3 c1 e9 04 shr ecx, 4 00ce6 03 c8 add ecx, eax 00ce8 81 e1 0f 0f 0f 0f and ecx, 252645135 ; 0f0f0f0fH ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits 00cee 8b c1 mov eax, ecx 00cf0 c1 e8 08 shr eax, 8 00cf3 03 c8 add ecx, eax ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits 00cf5 8b c1 mov eax, ecx 00cf7 c1 e8 10 shr eax, 16 00cfa 03 c1 add eax, ecx ; 4908 : return a & 0xff; 00cfc 0f b6 f8 movzx edi, al ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } 00cff 41 83 fd 08 cmp r13d, 8 00d03 0f 87 60 05 00 00 ja $LN86@stbi__bmp_ 00d09 41 83 fc 08 cmp r12d, 8 00d0d 0f 87 56 05 00 00 ja $LN86@stbi__bmp_ 00d13 41 83 ff 08 cmp r15d, 8 00d17 0f 87 4c 05 00 00 ja $LN86@stbi__bmp_ 00d1d 83 ff 08 cmp edi, 8 00d20 0f 87 43 05 00 00 ja $LN86@stbi__bmp_ 00d26 44 8b 4c 24 34 mov r9d, DWORD PTR pad$2$[rsp] $LN85@stbi__bmp_: ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { 00d2b 33 c0 xor eax, eax 00d2d 44 8b d0 mov r10d, eax 00d30 89 84 24 48 05 00 00 mov DWORD PTR j$3$[rsp], eax 00d37 8b 43 04 mov eax, DWORD PTR [rbx+4] 00d3a 85 c0 test eax, eax 00d3c 0f 8e 12 04 00 00 jle $LN18@stbi__bmp_ ; 4929 : v >>= (8 - bits); 00d42 b9 08 00 00 00 mov ecx, 8 00d47 48 89 bc 24 98 00 00 00 mov QWORD PTR tv4023[rsp], rdi ; 4925 : v <<= -shift; 00d4f 41 8b c3 mov eax, r11d 00d52 f7 d8 neg eax 00d54 89 44 24 6c mov DWORD PTR tv4035[rsp], eax ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); 00d58 8b c1 mov eax, ecx 00d5a 41 2b c5 sub eax, r13d 00d5d 89 44 24 70 mov DWORD PTR tv4034[rsp], eax ; 4925 : v <<= -shift; 00d61 41 8b c6 mov eax, r14d 00d64 f7 d8 neg eax 00d66 89 44 24 74 mov DWORD PTR tv4033[rsp], eax ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); 00d6a 8b c1 mov eax, ecx 00d6c 41 2b c4 sub eax, r12d 00d6f 89 44 24 78 mov DWORD PTR tv4032[rsp], eax ; 4925 : v <<= -shift; 00d73 41 8b c0 mov eax, r8d 00d76 f7 d8 neg eax 00d78 89 44 24 7c mov DWORD PTR tv4030[rsp], eax ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); 00d7c 8b c1 mov eax, ecx 00d7e 41 2b c7 sub eax, r15d 00d81 89 84 24 80 00 00 00 mov DWORD PTR tv4029[rsp], eax ; 4925 : v <<= -shift; 00d88 8b c2 mov eax, edx 00d8a f7 d8 neg eax 00d8c 89 84 24 84 00 00 00 mov DWORD PTR tv4028[rsp], eax ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); 00d93 2b cf sub ecx, edi 00d95 41 8b c5 mov eax, r13d 00d98 4c 8b 6c 24 58 mov r13, QWORD PTR $T22[rsp] 00d9d 48 89 84 24 c8 00 00 00 mov QWORD PTR tv4026[rsp], rax 00da5 89 8c 24 88 00 00 00 mov DWORD PTR tv4027[rsp], ecx 00dac 41 8b cc mov ecx, r12d 00daf 45 8b e2 mov r12d, r10d 00db2 41 8b c7 mov eax, r15d 00db5 48 89 84 24 d8 00 00 00 mov QWORD PTR tv4024[rsp], rax 00dbd 48 89 8c 24 d0 00 00 00 mov QWORD PTR tv4025[rsp], rcx $LL19@stbi__bmp_: ; 5208 : if (easy) { 00dc5 8b 03 mov eax, DWORD PTR [rbx] 00dc7 45 33 ff xor r15d, r15d 00dca 49 63 cc movsxd rcx, r12d 00dcd 4d 85 ed test r13, r13 00dd0 0f 84 83 01 00 00 je $LN87@stbi__bmp_ ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { 00dd6 85 c0 test eax, eax 00dd8 0f 8e 07 03 00 00 jle $LN24@stbi__bmp_ 00dde 4c 8d 34 0e lea r14, QWORD PTR [rsi+rcx] 00de2 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 00de6 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL22@stbi__bmp_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00df0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00df7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00dfe 73 0f jae SHORT $LN157@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00e00 0f b6 08 movzx ecx, BYTE PTR [rax] 00e03 48 ff c0 inc rax 00e06 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00e0d eb 2a jmp SHORT $LN156@stbi__bmp_ $LN157@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00e0f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00e13 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 00e17 74 1e je SHORT $LN158@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00e19 48 8b cb mov rcx, rbx 00e1c e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00e21 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00e28 0f b6 08 movzx ecx, BYTE PTR [rax] 00e2b 48 ff c0 inc rax 00e2e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00e35 eb 02 jmp SHORT $LN156@stbi__bmp_ $LN158@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00e37 32 c9 xor cl, cl $LN156@stbi__bmp_: ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); 00e39 41 88 4e 02 mov BYTE PTR [r14+2], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00e3d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00e44 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00e4b 73 0f jae SHORT $LN153@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00e4d 0f b6 08 movzx ecx, BYTE PTR [rax] 00e50 48 ff c0 inc rax 00e53 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00e5a eb 25 jmp SHORT $LN152@stbi__bmp_ $LN153@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00e5c 83 3f 00 cmp DWORD PTR [rdi], 0 00e5f 74 1e je SHORT $LN154@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00e61 48 8b cb mov rcx, rbx 00e64 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00e69 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00e70 0f b6 08 movzx ecx, BYTE PTR [rax] 00e73 48 ff c0 inc rax 00e76 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00e7d eb 02 jmp SHORT $LN152@stbi__bmp_ $LN154@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00e7f 32 c9 xor cl, cl $LN152@stbi__bmp_: ; 5212 : out[z + 1] = stbi__get8(s); 00e81 41 88 4e 01 mov BYTE PTR [r14+1], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00e85 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00e8c 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00e93 73 0f jae SHORT $LN149@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00e95 0f b6 08 movzx ecx, BYTE PTR [rax] 00e98 48 ff c0 inc rax 00e9b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00ea2 eb 25 jmp SHORT $LN148@stbi__bmp_ $LN149@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00ea4 83 3f 00 cmp DWORD PTR [rdi], 0 00ea7 74 1e je SHORT $LN150@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00ea9 48 8b cb mov rcx, rbx 00eac e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00eb1 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00eb8 0f b6 08 movzx ecx, BYTE PTR [rax] 00ebb 48 ff c0 inc rax 00ebe 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00ec5 eb 02 jmp SHORT $LN148@stbi__bmp_ $LN150@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00ec7 32 c9 xor cl, cl $LN148@stbi__bmp_: ; 5213 : out[z + 0] = stbi__get8(s); 00ec9 41 88 0e mov BYTE PTR [r14], cl ; 5214 : z += 3; 00ecc 41 83 c4 03 add r12d, 3 00ed0 49 83 c6 03 add r14, 3 ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); 00ed4 49 83 fd 02 cmp r13, 2 00ed8 75 53 jne SHORT $LN99@stbi__bmp_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00eda 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00ee1 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00ee8 73 0f jae SHORT $LN207@stbi__bmp_ ; 1078 : return *s->img_buffer++; 00eea 0f b6 08 movzx ecx, BYTE PTR [rax] 00eed 48 ff c0 inc rax 00ef0 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00ef7 eb 26 jmp SHORT $LN525@stbi__bmp_ $LN207@stbi__bmp_: ; 1079 : if (s->read_from_callbacks) { 00ef9 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00efd 74 1e je SHORT $LN208@stbi__bmp_ ; 1080 : stbi__refill_buffer(s); 00eff 48 8b cb mov rcx, rbx 00f02 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00f07 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00f0e 0f b6 08 movzx ecx, BYTE PTR [rax] 00f11 48 ff c0 inc rax 00f14 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00f1b eb 02 jmp SHORT $LN525@stbi__bmp_ $LN208@stbi__bmp_: ; 1082 : } ; 1083 : return 0; 00f1d 32 c9 xor cl, cl $LN525@stbi__bmp_: ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); 00f1f ba 30 00 00 00 mov edx, 48 ; 00000030H 00f24 48 8b c3 mov rax, rbx 00f27 48 8d 3c 13 lea rdi, QWORD PTR [rbx+rdx] 00f2b eb 06 jmp SHORT $LN100@stbi__bmp_ $LN99@stbi__bmp_: 00f2d b1 ff mov cl, 255 ; 000000ffH 00f2f 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] $LN100@stbi__bmp_: ; 5216 : all_a |= a; 00f33 0f b6 c1 movzx eax, cl 00f36 09 44 24 38 or DWORD PTR all_a$1$[rsp], eax ; 5217 : if (target == 4) out[z++] = a; 00f3a 83 fd 04 cmp ebp, 4 00f3d 75 09 jne SHORT $LN20@stbi__bmp_ 00f3f 41 ff c4 inc r12d 00f42 41 88 0e mov BYTE PTR [r14], cl 00f45 49 ff c6 inc r14 $LN20@stbi__bmp_: ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { 00f48 41 ff c7 inc r15d 00f4b 44 3b 3b cmp r15d, DWORD PTR [rbx] 00f4e 0f 8c 9c fe ff ff jl $LL22@stbi__bmp_ ; 5218 : } ; 5219 : } 00f54 e9 7f 01 00 00 jmp $LN526@stbi__bmp_ $LN87@stbi__bmp_: ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { 00f59 85 c0 test eax, eax 00f5b 0f 8e 84 01 00 00 jle $LN24@stbi__bmp_ 00f61 44 8b 6c 24 44 mov r13d, DWORD PTR gshift$1$[rsp] 00f66 4c 8d 34 0e lea r14, QWORD PTR [rsi+rcx] 00f6a 8b 74 24 40 mov esi, DWORD PTR info$3$[rsp] 00f6e 66 90 npad 2 $LL25@stbi__bmp_: ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); 00f70 48 8b cb mov rcx, rbx 00f73 e8 00 00 00 00 call stbi__get16le 00f78 83 fe 10 cmp esi, 16 00f7b 74 17 je SHORT $LN102@stbi__bmp_ ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; 00f7d 48 8b cb mov rcx, rbx 00f80 8b f8 mov edi, eax 00f82 e8 00 00 00 00 call stbi__get16le 00f87 c1 e0 10 shl eax, 16 00f8a 03 c7 add eax, edi 00f8c 48 8b bc 24 98 00 00 00 mov rdi, QWORD PTR tv4023[rsp] $LN102@stbi__bmp_: ; 4924 : if (shift < 0) 00f94 44 8b 5c 24 60 mov r11d, DWORD PTR rshift$1$[rsp] ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); 00f99 8b d0 mov edx, eax 00f9b 23 54 24 48 and edx, DWORD PTR mr$1$[rsp] ; 4924 : if (shift < 0) 00f9f 45 85 db test r11d, r11d 00fa2 79 08 jns SHORT $LN169@stbi__bmp_ ; 4925 : v <<= -shift; 00fa4 8b 4c 24 6c mov ecx, DWORD PTR tv4035[rsp] 00fa8 d3 e2 shl edx, cl 00faa eb 05 jmp SHORT $LN170@stbi__bmp_ $LN169@stbi__bmp_: ; 4926 : else ; 4927 : v >>= shift; 00fac 41 8b cb mov ecx, r11d 00faf d3 ea shr edx, cl $LN170@stbi__bmp_: ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 00fb1 4c 8b 9c 24 c8 00 00 00 mov r11, QWORD PTR tv4026[rsp] 00fb9 4c 8d 0d 00 00 00 00 lea r9, OFFSET FLAT:__ImageBase 00fc0 8b 4c 24 70 mov ecx, DWORD PTR tv4034[rsp] 00fc4 d3 ea shr edx, cl 00fc6 43 0f af 94 99 00 00 00 00 imul edx, DWORD PTR ?mul_table@?1??stbi__shiftsigned@@9@9[r9+r11*4] 00fcf 43 8b 8c 99 00 00 00 00 mov ecx, DWORD PTR ?shift_table@?1??stbi__shiftsigned@@9@9[r9+r11*4] 00fd7 d3 fa sar edx, cl ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); 00fd9 41 88 16 mov BYTE PTR [r14], dl ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); 00fdc 8b d0 mov edx, eax 00fde 23 54 24 4c and edx, DWORD PTR mg$1$[rsp] ; 4924 : if (shift < 0) 00fe2 45 85 ed test r13d, r13d 00fe5 79 08 jns SHORT $LN165@stbi__bmp_ ; 4925 : v <<= -shift; 00fe7 8b 4c 24 74 mov ecx, DWORD PTR tv4033[rsp] 00feb d3 e2 shl edx, cl 00fed eb 05 jmp SHORT $LN166@stbi__bmp_ $LN165@stbi__bmp_: ; 4926 : else ; 4927 : v >>= shift; 00fef 41 8b cd mov ecx, r13d 00ff2 d3 ea shr edx, cl $LN166@stbi__bmp_: ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 00ff4 4c 8b 9c 24 d0 00 00 00 mov r11, QWORD PTR tv4025[rsp] 00ffc 8b 4c 24 78 mov ecx, DWORD PTR tv4032[rsp] ; 4924 : if (shift < 0) 01000 44 8b 44 24 3c mov r8d, DWORD PTR bshift$1$[rsp] ; 4929 : v >>= (8 - bits); 01005 d3 ea shr edx, cl ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 01007 43 0f af 94 99 00 00 00 00 imul edx, DWORD PTR ?mul_table@?1??stbi__shiftsigned@@9@9[r9+r11*4] 01010 43 8b 8c 99 00 00 00 00 mov ecx, DWORD PTR ?shift_table@?1??stbi__shiftsigned@@9@9[r9+r11*4] 01018 d3 fa sar edx, cl ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); 0101a 41 88 56 01 mov BYTE PTR [r14+1], dl ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); 0101e 8b d0 mov edx, eax 01020 23 54 24 50 and edx, DWORD PTR mb$1$[rsp] ; 4924 : if (shift < 0) 01024 45 85 c0 test r8d, r8d 01027 79 08 jns SHORT $LN161@stbi__bmp_ ; 4925 : v <<= -shift; 01029 8b 4c 24 7c mov ecx, DWORD PTR tv4030[rsp] 0102d d3 e2 shl edx, cl 0102f eb 05 jmp SHORT $LN162@stbi__bmp_ $LN161@stbi__bmp_: ; 4926 : else ; 4927 : v >>= shift; 01031 41 8b c8 mov ecx, r8d 01034 d3 ea shr edx, cl $LN162@stbi__bmp_: ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 01036 4c 8b 84 24 d8 00 00 00 mov r8, QWORD PTR tv4024[rsp] ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); 0103e 41 83 c4 03 add r12d, 3 ; 4929 : v >>= (8 - bits); 01042 8b 8c 24 80 00 00 00 mov ecx, DWORD PTR tv4029[rsp] ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); 01049 44 8b 54 24 64 mov r10d, DWORD PTR ma$1$[rsp] ; 4929 : v >>= (8 - bits); 0104e d3 ea shr edx, cl ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 01050 43 0f af 94 81 00 00 00 00 imul edx, DWORD PTR ?mul_table@?1??stbi__shiftsigned@@9@9[r9+r8*4] 01059 43 8b 8c 81 00 00 00 00 mov ecx, DWORD PTR ?shift_table@?1??stbi__shiftsigned@@9@9[r9+r8*4] 01061 d3 fa sar edx, cl ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); 01063 41 88 56 02 mov BYTE PTR [r14+2], dl 01067 49 83 c6 03 add r14, 3 ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); 0106b 45 85 d2 test r10d, r10d 0106e 74 38 je SHORT $LN103@stbi__bmp_ ; 4924 : if (shift < 0) 01070 8b 54 24 30 mov edx, DWORD PTR ashift$1$[rsp] ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); 01074 41 23 c2 and eax, r10d ; 4924 : if (shift < 0) 01077 85 d2 test edx, edx 01079 79 0b jns SHORT $LN211@stbi__bmp_ ; 4925 : v <<= -shift; 0107b 8b 8c 24 84 00 00 00 mov ecx, DWORD PTR tv4028[rsp] 01082 d3 e0 shl eax, cl 01084 eb 04 jmp SHORT $LN212@stbi__bmp_ $LN211@stbi__bmp_: ; 4926 : else ; 4927 : v >>= shift; 01086 8b ca mov ecx, edx 01088 d3 e8 shr eax, cl $LN212@stbi__bmp_: ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); 0108a 8b 8c 24 88 00 00 00 mov ecx, DWORD PTR tv4027[rsp] 01091 d3 e8 shr eax, cl ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; 01093 41 0f af 84 b9 00 00 00 00 imul eax, DWORD PTR ?mul_table@?1??stbi__shiftsigned@@9@9[r9+rdi*4] 0109c 41 8b 8c b9 00 00 00 00 mov ecx, DWORD PTR ?shift_table@?1??stbi__shiftsigned@@9@9[r9+rdi*4] 010a4 d3 f8 sar eax, cl ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); 010a6 eb 05 jmp SHORT $LN104@stbi__bmp_ $LN103@stbi__bmp_: 010a8 b8 ff 00 00 00 mov eax, 255 ; 000000ffH $LN104@stbi__bmp_: ; 5229 : all_a |= a; 010ad 09 44 24 38 or DWORD PTR all_a$1$[rsp], eax ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); 010b1 83 fd 04 cmp ebp, 4 010b4 75 09 jne SHORT $LN23@stbi__bmp_ 010b6 41 ff c4 inc r12d 010b9 41 88 06 mov BYTE PTR [r14], al 010bc 49 ff c6 inc r14 $LN23@stbi__bmp_: ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { 010bf 41 ff c7 inc r15d 010c2 44 3b 3b cmp r15d, DWORD PTR [rbx] 010c5 0f 8c a5 fe ff ff jl $LL25@stbi__bmp_ 010cb 48 8b b4 24 90 00 00 00 mov rsi, QWORD PTR out$1$[rsp] 010d3 4c 8b 6c 24 58 mov r13, QWORD PTR $T22[rsp] $LN526@stbi__bmp_: ; 1107 : if (n == 0) return; // already there! 010d8 44 8b 94 24 48 05 00 00 mov r10d, DWORD PTR j$3$[rsp] 010e0 44 8b 4c 24 34 mov r9d, DWORD PTR pad$2$[rsp] $LN24@stbi__bmp_: 010e5 45 85 c9 test r9d, r9d 010e8 74 4b je SHORT $LN17@stbi__bmp_ ; 1111 : } ; 1112 : if (s->io.read) { 010ea 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 010ef 74 3a je SHORT $LN360@stbi__bmp_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 010f1 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 010f7 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 010fd 41 3b c9 cmp ecx, r9d 01100 7d 29 jge SHORT $LN360@stbi__bmp_ ; 1115 : s->img_buffer = s->img_buffer_end; 01102 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 01109 41 8b d1 mov edx, r9d 0110c 2b d1 sub edx, ecx 0110e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 01115 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 01119 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 0111c 44 8b 4c 24 34 mov r9d, DWORD PTR pad$2$[rsp] 01121 44 8b 94 24 48 05 00 00 mov r10d, DWORD PTR j$3$[rsp] 01129 eb 0a jmp SHORT $LN17@stbi__bmp_ $LN360@stbi__bmp_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0112b 41 8b c1 mov eax, r9d 0112e 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax $LN17@stbi__bmp_: ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { 01135 8b 43 04 mov eax, DWORD PTR [rbx+4] 01138 41 ff c2 inc r10d 0113b 48 8b bc 24 98 00 00 00 mov rdi, QWORD PTR tv4023[rsp] 01143 44 89 94 24 48 05 00 00 mov DWORD PTR j$3$[rsp], r10d 0114b 44 3b d0 cmp r10d, eax 0114e 0f 8c 71 fc ff ff jl $LL19@stbi__bmp_ $LN18@stbi__bmp_: ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) 01154 83 fd 04 cmp ebp, 4 01157 75 22 jne SHORT $LN27@stbi__bmp_ 01159 83 7c 24 38 00 cmp DWORD PTR all_a$1$[rsp], 0 0115e 75 1b jne SHORT $LN27@stbi__bmp_ ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) 01160 0f af 03 imul eax, DWORD PTR [rbx] 01163 8d 04 85 ff ff ff ff lea eax, DWORD PTR [rax*4-1] 0116a 48 63 c8 movsxd rcx, eax 0116d 85 c0 test eax, eax 0116f 78 0a js SHORT $LN27@stbi__bmp_ $LL28@stbi__bmp_: ; 5240 : out[i] = 255; 01171 c6 04 31 ff mov BYTE PTR [rcx+rsi], 255 ; 000000ffH 01175 48 83 e9 04 sub rcx, 4 01179 79 f6 jns SHORT $LL28@stbi__bmp_ $LN27@stbi__bmp_: ; 5241 : ; 5242 : if (flip_vertically) { 0117b 83 bc 24 8c 00 00 00 00 cmp DWORD PTR tv4126[rsp], 0 01183 0f 8e 7b 00 00 00 jle $LN30@stbi__bmp_ ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { 01189 8b 53 04 mov edx, DWORD PTR [rbx+4] 0118c 45 33 c0 xor r8d, r8d 0118f 45 8b d0 mov r10d, r8d 01192 f7 c2 fe ff ff ff test edx, -2 01198 7e 6a jle SHORT $LN30@stbi__bmp_ 0119a 66 0f 1f 44 00 00 npad 6 $LL31@stbi__bmp_: ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; 011a0 8b 0b mov ecx, DWORD PTR [rbx] ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; 011a2 41 2b d2 sub edx, r10d 011a5 ff ca dec edx 011a7 44 8b c9 mov r9d, ecx 011aa 0f af d1 imul edx, ecx 011ad 45 0f af ca imul r9d, r10d ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { 011b1 0f af cd imul ecx, ebp 011b4 0f af d5 imul edx, ebp 011b7 44 0f af cd imul r9d, ebp 011bb 48 03 d6 add rdx, rsi 011be 4c 03 ce add r9, rsi 011c1 85 c9 test ecx, ecx 011c3 7e 2a jle SHORT $LN29@stbi__bmp_ ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; 011c5 4c 2b ca sub r9, rdx 011c8 0f 1f 84 00 00 00 00 00 npad 8 $LL34@stbi__bmp_: ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; 011d0 0f b6 02 movzx eax, BYTE PTR [rdx] 011d3 41 ff c0 inc r8d 011d6 42 0f b6 0c 0a movzx ecx, BYTE PTR [rdx+r9] 011db 42 88 04 0a mov BYTE PTR [rdx+r9], al 011df 8b c5 mov eax, ebp 011e1 88 0a mov BYTE PTR [rdx], cl 011e3 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 011e7 0f af 03 imul eax, DWORD PTR [rbx] 011ea 44 3b c0 cmp r8d, eax 011ed 7c e1 jl SHORT $LL34@stbi__bmp_ $LN29@stbi__bmp_: ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { 011ef 8b 53 04 mov edx, DWORD PTR [rbx+4] 011f2 41 ff c2 inc r10d 011f5 8b c2 mov eax, edx 011f7 41 b8 00 00 00 00 mov r8d, 0 011fd d1 f8 sar eax, 1 011ff 44 3b d0 cmp r10d, eax 01202 7c 9c jl SHORT $LL31@stbi__bmp_ $LN30@stbi__bmp_: ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { 01204 44 8b 84 24 40 05 00 00 mov r8d, DWORD PTR req_comp$[rsp] 0120c 45 85 c0 test r8d, r8d 0120f 74 25 je SHORT $LN94@stbi__bmp_ 01211 44 3b c5 cmp r8d, ebp 01214 74 20 je SHORT $LN94@stbi__bmp_ ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); 01216 8b 43 04 mov eax, DWORD PTR [rbx+4] 01219 8b d5 mov edx, ebp 0121b 44 8b 0b mov r9d, DWORD PTR [rbx] 0121e 48 8b ce mov rcx, rsi 01221 89 44 24 20 mov DWORD PTR [rsp+32], eax 01225 e8 00 00 00 00 call stbi__convert_format 0122a 48 8b f0 mov rsi, rax ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure 0122d 48 85 c0 test rax, rax 01230 0f 84 b3 00 00 00 je $LN373@stbi__bmp_ $LN94@stbi__bmp_: ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; 01236 8b 03 mov eax, DWORD PTR [rbx] 01238 48 8b 8c 24 28 05 00 00 mov rcx, QWORD PTR x$[rsp] 01240 89 01 mov DWORD PTR [rcx], eax ; 5259 : *y = s->img_y; 01242 48 8b 8c 24 30 05 00 00 mov rcx, QWORD PTR y$[rsp] 0124a 8b 43 04 mov eax, DWORD PTR [rbx+4] 0124d 89 01 mov DWORD PTR [rcx], eax ; 5260 : if (comp) *comp = s->img_n; 0124f 48 8b 8c 24 38 05 00 00 mov rcx, QWORD PTR comp$[rsp] 01257 48 85 c9 test rcx, rcx 0125a 74 05 je SHORT $LN95@stbi__bmp_ 0125c 8b 43 08 mov eax, DWORD PTR [rbx+8] 0125f 89 01 mov DWORD PTR [rcx], eax $LN95@stbi__bmp_: ; 5261 : return out; 01261 48 8b c6 mov rax, rsi 01264 e9 82 00 00 00 jmp $LN1@stbi__bmp_ $LN86@stbi__bmp_: ; 5262 : } 01269 48 8b ce mov rcx, rsi 0126c ff 15 00 00 00 00 call QWORD PTR __imp_free 01272 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 01278 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 01281 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 01285 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09DAEBACAB@bad?5masks@ 0128c eb 52 jmp SHORT $LN528@stbi__bmp_ $LN355@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 0128e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 01294 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0129d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 012a1 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 012a8 eb 36 jmp SHORT $LN528@stbi__bmp_ $LN47@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 012aa 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 012b0 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 012b9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 012bd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@JDPIFELH@bad?5offset@ ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); 012c4 eb 1a jmp SHORT $LN528@stbi__bmp_ $LN44@stbi__bmp_: ; 431 : stbi__g_failure_reason = str; 012c6 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 012cc 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 012d5 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 012d9 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@PJHPAMCH@bad?5header@ $LN528@stbi__bmp_: ; 5262 : } 012e0 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 012e5 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN373@stbi__bmp_: 012e9 33 c0 xor eax, eax $LN1@stbi__bmp_: 012eb 48 8b 9c 24 20 05 00 00 mov rbx, QWORD PTR [rsp+1312] 012f3 48 81 c4 e0 04 00 00 add rsp, 1248 ; 000004e0H 012fa 41 5f pop r15 012fc 41 5e pop r14 012fe 41 5d pop r13 01300 41 5c pop r12 01302 5f pop rdi 01303 5e pop rsi 01304 5d pop rbp 01305 c3 ret 0 stbi__bmp_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__tga_get_comp _TEXT SEGMENT bits_per_pixel$ = 8 is_grey$ = 16 is_rgb16$ = 24 stbi__tga_get_comp PROC ; COMDAT ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; 00000 4d 85 c0 test r8, r8 00003 74 07 je SHORT $LN4@stbi__tga_ 00005 41 c7 00 00 00 00 00 mov DWORD PTR [r8], 0 $LN4@stbi__tga_: ; 5273 : switch (bits_per_pixel) { 0000c 44 8b c9 mov r9d, ecx 0000f 41 83 e9 08 sub r9d, 8 00013 74 43 je SHORT $LN5@stbi__tga_ 00015 41 83 e9 07 sub r9d, 7 00019 74 2b je SHORT $LN7@stbi__tga_ 0001b 41 83 e9 01 sub r9d, 1 0001f 74 1b je SHORT $LN6@stbi__tga_ 00021 41 83 e9 08 sub r9d, 8 00025 74 09 je SHORT $LN10@stbi__tga_ 00027 41 83 f9 08 cmp r9d, 8 0002b 74 03 je SHORT $LN10@stbi__tga_ ; 5281 : default: return 0; 0002d 33 c0 xor eax, eax ; 5282 : } ; 5283 : } 0002f c3 ret 0 $LN10@stbi__tga_: ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; 00030 8b c1 mov eax, ecx 00032 99 cdq 00033 83 e2 07 and edx, 7 00036 03 c2 add eax, edx 00038 c1 f8 03 sar eax, 3 ; 5282 : } ; 5283 : } 0003b c3 ret 0 $LN6@stbi__tga_: ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; 0003c 85 d2 test edx, edx 0003e 74 06 je SHORT $LN7@stbi__tga_ 00040 b8 02 00 00 00 mov eax, 2 ; 5282 : } ; 5283 : } 00045 c3 ret 0 $LN7@stbi__tga_: ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; 00046 4d 85 c0 test r8, r8 00049 74 07 je SHORT $LN9@stbi__tga_ 0004b 41 c7 00 01 00 00 00 mov DWORD PTR [r8], 1 $LN9@stbi__tga_: ; 5278 : return STBI_rgb; 00052 b8 03 00 00 00 mov eax, 3 ; 5282 : } ; 5283 : } 00057 c3 ret 0 $LN5@stbi__tga_: ; 5274 : case 8: return STBI_grey; 00058 b8 01 00 00 00 mov eax, 1 ; 5282 : } ; 5283 : } 0005d c3 ret 0 stbi__tga_get_comp ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__tga_test _TEXT SEGMENT s$ = 64 stbi__tga_test PROC ; COMDAT ; 5353 : { 00000 40 53 push rbx 00002 57 push rdi 00003 41 56 push r14 00005 48 83 ec 20 sub rsp, 32 ; 00000020H 00009 48 8b d9 mov rbx, rcx ; 5354 : int res = 0; 0000c 45 33 f6 xor r14d, r14d ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000f 48 8b 89 c0 00 00 00 mov rcx, QWORD PTR [rcx+192] 00016 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 0001d 73 0c jae SHORT $LN14@stbi__tga_ ; 1078 : return *s->img_buffer++; 0001f 48 ff c1 inc rcx 00022 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00029 eb 1c jmp SHORT $LN15@stbi__tga_ $LN14@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 0002b 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 0002f 74 16 je SHORT $LN15@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00031 48 8b cb mov rcx, rbx 00034 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00039 48 ff 83 c0 00 00 00 inc QWORD PTR [rbx+192] 00040 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] $LN15@stbi__tga_: 00047 48 89 6c 24 40 mov QWORD PTR [rsp+64], rbp 0004c 48 89 74 24 48 mov QWORD PTR [rsp+72], rsi ; 1077 : if (s->img_buffer < s->img_buffer_end) 00051 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 00058 73 08 jae SHORT $LN18@stbi__tga_ ; 1078 : return *s->img_buffer++; 0005a 0f b6 29 movzx ebp, BYTE PTR [rcx] 0005d 48 ff c1 inc rcx 00060 eb 1c jmp SHORT $LN91@stbi__tga_ $LN18@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00062 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 00066 74 2d je SHORT $LN19@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00068 48 8b cb mov rcx, rbx 0006b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00070 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00077 0f b6 28 movzx ebp, BYTE PTR [rax] 0007a 48 8d 48 01 lea rcx, QWORD PTR [rax+1] $LN91@stbi__tga_: ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type 0007e 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00085 40 0f b6 f5 movzx esi, bpl ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed 00089 40 80 fd 01 cmp bpl, 1 0008d 0f 87 f0 01 00 00 ja $errorEnd$95 00093 eb 07 jmp SHORT $LN54@stbi__tga_ $LN19@stbi__tga_: ; 1083 : return 0; 00095 40 32 ed xor bpl, bpl 00098 40 0f b6 f5 movzx esi, bpl $LN54@stbi__tga_: 0009c 4c 89 7c 24 50 mov QWORD PTR [rsp+80], r15 ; 1077 : if (s->img_buffer < s->img_buffer_end) 000a1 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 000a8 73 08 jae SHORT $LN22@stbi__tga_ ; 1078 : return *s->img_buffer++; 000aa 0f b6 11 movzx edx, BYTE PTR [rcx] 000ad 48 ff c1 inc rcx 000b0 eb 20 jmp SHORT $LN21@stbi__tga_ $LN22@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 000b2 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 000b6 74 18 je SHORT $LN23@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 000b8 48 8b cb mov rcx, rbx 000bb e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000c0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000c7 0f b6 10 movzx edx, BYTE PTR [rax] 000ca 48 8d 48 01 lea rcx, QWORD PTR [rax+1] 000ce eb 02 jmp SHORT $LN21@stbi__tga_ $LN23@stbi__tga_: ; 1082 : } ; 1083 : return 0; 000d0 32 d2 xor dl, dl $LN21@stbi__tga_: ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image 000d2 41 bf 00 81 01 01 mov r15d, 16875776 ; 01018100H 000d8 40 80 fe 01 cmp sil, 1 000dc 0f 85 d3 00 00 00 jne $LN3@stbi__tga_ ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 000e2 fe ca dec dl 000e4 f6 c2 f7 test dl, 247 ; 000000f7H 000e7 0f 85 91 01 00 00 jne $LN90@stbi__tga_ ; 1112 : if (s->io.read) { 000ed be 04 00 00 00 mov esi, 4 000f2 4c 39 73 10 cmp QWORD PTR [rbx+16], r14 000f6 74 2b je SHORT $LN29@stbi__tga_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 000f8 44 8b 83 c8 00 00 00 mov r8d, DWORD PTR [rbx+200] 000ff 44 2b c1 sub r8d, ecx ; 1114 : if (blen < n) { 00102 44 3b c6 cmp r8d, esi 00105 7d 1c jge SHORT $LN29@stbi__tga_ ; 1115 : s->img_buffer = s->img_buffer_end; 00107 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0010e 8b d6 mov edx, esi 00110 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 00114 41 2b d0 sub edx, r8d 00117 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0011e ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 00121 eb 0b jmp SHORT $LN25@stbi__tga_ $LN29@stbi__tga_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00123 48 8d 41 04 lea rax, QWORD PTR [rcx+4] 00127 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax $LN25@stbi__tga_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0012e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00135 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0013c 73 09 jae SHORT $LN32@stbi__tga_ ; 1078 : return *s->img_buffer++; 0013e 4c 8d 40 01 lea r8, QWORD PTR [rax+1] 00142 49 8b d0 mov rdx, r8 00145 eb 20 jmp SHORT $LN92@stbi__tga_ $LN32@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00147 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 0014b 0f 84 2d 01 00 00 je $LN90@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00151 48 8b cb mov rcx, rbx 00154 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00159 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00160 48 8d 50 01 lea rdx, QWORD PTR [rax+1] 00164 44 8b c2 mov r8d, edx $LN92@stbi__tga_: ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; 00167 0f b6 08 movzx ecx, BYTE PTR [rax] 0016a 80 f9 18 cmp cl, 24 0016d 77 09 ja SHORT $LN59@stbi__tga_ 0016f 0f b6 c1 movzx eax, cl 00172 41 0f a3 c7 bt r15d, eax 00176 72 09 jb SHORT $LN6@stbi__tga_ $LN59@stbi__tga_: 00178 80 f9 20 cmp cl, 32 ; 00000020H 0017b 0f 85 fd 00 00 00 jne $LN90@stbi__tga_ $LN6@stbi__tga_: ; 1112 : if (s->io.read) { 00181 4c 39 73 10 cmp QWORD PTR [rbx+16], r14 00185 74 28 je SHORT $LN39@stbi__tga_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00187 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 0018d 41 2b c8 sub ecx, r8d ; 1114 : if (blen < n) { 00190 3b ce cmp ecx, esi 00192 7d 1b jge SHORT $LN39@stbi__tga_ ; 1115 : s->img_buffer = s->img_buffer_end; 00194 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0019b 2b f1 sub esi, ecx 0019d 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 001a1 8b d6 mov edx, esi 001a3 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001aa ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 001ad eb 5b jmp SHORT $LN41@stbi__tga_ $LN39@stbi__tga_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 001af 48 8d 42 04 lea rax, QWORD PTR [rdx+4] ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } 001b3 eb 4e jmp SHORT $LN93@stbi__tga_ $LN3@stbi__tga_: ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE 001b5 8d 42 fe lea eax, DWORD PTR [rdx-2] 001b8 a8 f6 test al, 246 ; 000000f6H 001ba 75 05 jne SHORT $LN61@stbi__tga_ 001bc 80 fa 0b cmp dl, 11 001bf 75 09 jne SHORT $LN7@stbi__tga_ $LN61@stbi__tga_: 001c1 80 fa 0b cmp dl, 11 001c4 0f 85 b4 00 00 00 jne $LN90@stbi__tga_ $LN7@stbi__tga_: ; 1112 : if (s->io.read) { 001ca 4c 39 73 10 cmp QWORD PTR [rbx+16], r14 001ce 74 2f je SHORT $LN45@stbi__tga_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 001d0 44 8b 83 c8 00 00 00 mov r8d, DWORD PTR [rbx+200] 001d7 44 2b c1 sub r8d, ecx ; 1114 : if (blen < n) { 001da 41 83 f8 09 cmp r8d, 9 001de 7d 1f jge SHORT $LN45@stbi__tga_ ; 1115 : s->img_buffer = s->img_buffer_end; 001e0 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 001e7 ba 09 00 00 00 mov edx, 9 001ec 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 001f0 41 2b d0 sub edx, r8d 001f3 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001fa ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 001fd eb 0b jmp SHORT $LN41@stbi__tga_ $LN45@stbi__tga_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 001ff 48 8d 41 09 lea rax, QWORD PTR [rcx+9] $LN93@stbi__tga_: ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width 00203 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax $LN41@stbi__tga_: 0020a 48 8b cb mov rcx, rbx 0020d e8 00 00 00 00 call stbi__get16le 00212 83 f8 01 cmp eax, 1 00215 7c 67 jl SHORT $LN90@stbi__tga_ ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height 00217 48 8b cb mov rcx, rbx 0021a e8 00 00 00 00 call stbi__get16le 0021f 83 f8 01 cmp eax, 1 00222 7c 5a jl SHORT $LN90@stbi__tga_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00224 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] 0022b 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 00232 73 05 jae SHORT $LN48@stbi__tga_ ; 1078 : return *s->img_buffer++; 00234 0f b6 09 movzx ecx, BYTE PTR [rcx] 00237 eb 1c jmp SHORT $LN47@stbi__tga_ $LN48@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00239 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 0023d 74 14 je SHORT $LN49@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 0023f 48 8b cb mov rcx, rbx 00242 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00247 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0024e 0f b6 08 movzx ecx, BYTE PTR [rax] 00251 eb 02 jmp SHORT $LN47@stbi__tga_ $LN49@stbi__tga_: ; 1082 : } ; 1083 : return 0; 00253 32 c9 xor cl, cl $LN47@stbi__tga_: ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index 00255 40 80 fd 01 cmp bpl, 1 00259 75 0a jne SHORT $LN10@stbi__tga_ 0025b 80 f9 08 cmp cl, 8 0025e 74 18 je SHORT $LN11@stbi__tga_ 00260 80 f9 10 cmp cl, 16 00263 75 19 jne SHORT $LN90@stbi__tga_ $LN10@stbi__tga_: ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; 00265 80 f9 18 cmp cl, 24 00268 77 09 ja SHORT $LN63@stbi__tga_ 0026a 0f b6 c1 movzx eax, cl 0026d 41 0f a3 c7 bt r15d, eax 00271 72 05 jb SHORT $LN11@stbi__tga_ $LN63@stbi__tga_: 00273 80 f9 20 cmp cl, 32 ; 00000020H 00276 75 06 jne SHORT $LN90@stbi__tga_ $LN11@stbi__tga_: ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 00278 41 be 01 00 00 00 mov r14d, 1 $LN90@stbi__tga_: 0027e 4c 8b 7c 24 50 mov r15, QWORD PTR [rsp+80] $errorEnd$95: ; 342 : s->img_buffer = s->img_buffer_original; 00283 48 8b 8b d0 00 00 00 mov rcx, QWORD PTR [rbx+208] ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; 0028a 41 8b c6 mov eax, r14d 0028d 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] 00292 48 8b 6c 24 40 mov rbp, QWORD PTR [rsp+64] ; 342 : s->img_buffer = s->img_buffer_original; 00297 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0029e 48 8b 8b d8 00 00 00 mov rcx, QWORD PTR [rbx+216] 002a5 48 89 8b c8 00 00 00 mov QWORD PTR [rbx+200], rcx ; 5382 : } 002ac 48 83 c4 20 add rsp, 32 ; 00000020H 002b0 41 5e pop r14 002b2 5f pop rdi 002b3 5b pop rbx 002b4 c3 ret 0 stbi__tga_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__tga_read_rgb16 _TEXT SEGMENT s$ = 48 out$ = 56 stbi__tga_read_rgb16 PROC ; COMDAT ; 5386 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H 00006 48 8b da mov rbx, rdx ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); 00009 e8 00 00 00 00 call stbi__get16le ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; 0000e 44 0f b7 c0 movzx r8d, ax 00012 41 8b c0 mov eax, r8d 00015 c1 e8 0a shr eax, 10 00018 83 e0 1f and eax, 31 ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); 0001b 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 00021 b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 00026 f7 e9 imul ecx 00028 03 d1 add edx, ecx 0002a c1 fa 04 sar edx, 4 0002d 8b c2 mov eax, edx 0002f c1 e8 1f shr eax, 31 00032 03 d0 add edx, eax 00034 41 8b c0 mov eax, r8d 00037 c1 e8 05 shr eax, 5 0003a 41 83 e0 1f and r8d, 31 0003e 83 e0 1f and eax, 31 00041 88 13 mov BYTE PTR [rbx], dl ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); 00043 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 00049 b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 0004e f7 e9 imul ecx ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); 00050 b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 00055 03 d1 add edx, ecx 00057 c1 fa 04 sar edx, 4 0005a 8b ca mov ecx, edx 0005c c1 e9 1f shr ecx, 31 0005f 03 d1 add edx, ecx 00061 41 69 c8 ff 00 00 00 imul ecx, r8d, 255 ; 000000ffH 00068 88 53 01 mov BYTE PTR [rbx+1], dl 0006b f7 e9 imul ecx 0006d 03 d1 add edx, ecx 0006f c1 fa 04 sar edx, 4 00072 8b c2 mov eax, edx 00074 c1 e8 1f shr eax, 31 00077 03 d0 add edx, eax 00079 88 53 02 mov BYTE PTR [rbx+2], dl ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } 0007c 48 83 c4 20 add rsp, 32 ; 00000020H 00080 5b pop rbx 00081 c3 ret 0 stbi__tga_read_rgb16 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__tga_load _TEXT SEGMENT $T18 = 48 tga_comp$4$ = 52 tga_offset$1$ = 52 $T19 = 56 tga_rgb16$4$ = 60 tga_image_type$1$ = 60 tga_width$1$ = 64 tv2782 = 68 y$GSCopy$1$ = 72 tga_data$1$ = 72 tga_palette$1$ = 80 tga_palette_len$1$ = 88 RLE_repeating$1$ = 92 tga_bits_per_pixel$1$ = 96 tga_inverted$1$ = 100 x$GSCopy$1$ = 104 tv2753 = 104 req_comp$GSCopy$1$ = 112 comp$GSCopy$1$ = 120 tv2766 = 120 raw_data$ = 128 __$ArrayPad$ = 136 s$ = 224 x$ = 232 y$ = 240 comp$ = 248 req_comp$ = 256 ri$dead$ = 264 stbi__tga_load PROC ; COMDAT ; 5405 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 54 push r12 00007 41 55 push r13 00009 41 56 push r14 0000b 41 57 push r15 0000d 48 81 ec 98 00 00 00 sub rsp, 152 ; 00000098H 00014 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0001b 48 33 c4 xor rax, rsp 0001e 48 89 84 24 88 00 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00026 8b 84 24 00 01 00 00 mov eax, DWORD PTR req_comp$[rsp] 0002d 48 8b d9 mov rbx, rcx 00030 89 44 24 70 mov DWORD PTR req_comp$GSCopy$1$[rsp], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 00034 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 5405 : { 0003b 4c 89 4c 24 78 mov QWORD PTR comp$GSCopy$1$[rsp], r9 00040 4c 89 44 24 48 mov QWORD PTR y$GSCopy$1$[rsp], r8 00045 48 89 54 24 68 mov QWORD PTR x$GSCopy$1$[rsp], rdx ; 1077 : if (s->img_buffer < s->img_buffer_end) 0004a 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 00051 73 0f jae SHORT $LN67@stbi__tga_ ; 1078 : return *s->img_buffer++; 00053 0f b6 10 movzx edx, BYTE PTR [rax] 00056 48 ff c0 inc rax 00059 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax 00060 eb 23 jmp SHORT $LN374@stbi__tga_ $LN67@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00062 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00066 74 1b je SHORT $LN68@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00068 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0006d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00074 0f b6 10 movzx edx, BYTE PTR [rax] 00077 48 ff c0 inc rax 0007a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00081 eb 02 jmp SHORT $LN374@stbi__tga_ $LN68@stbi__tga_: ; 1082 : } ; 1083 : return 0; 00083 32 d2 xor dl, dl $LN374@stbi__tga_: ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); 00085 b9 30 00 00 00 mov ecx, 48 ; 00000030H 0008a 4c 8b c3 mov r8, rbx 0008d 48 8d 34 19 lea rsi, QWORD PTR [rcx+rbx] 00091 0f b6 ca movzx ecx, dl 00094 89 4c 24 34 mov DWORD PTR tga_offset$1$[rsp], ecx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00098 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0009f 73 13 jae SHORT $LN71@stbi__tga_ ; 1078 : return *s->img_buffer++; 000a1 0f b6 08 movzx ecx, BYTE PTR [rax] 000a4 48 ff c0 inc rax 000a7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000ae 88 4c 24 30 mov BYTE PTR $T18[rsp], cl 000b2 eb 2c jmp SHORT $LN70@stbi__tga_ $LN71@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 000b4 83 3e 00 cmp DWORD PTR [rsi], 0 000b7 74 22 je SHORT $LN72@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 000b9 48 8b cb mov rcx, rbx 000bc e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000c1 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000c8 0f b6 08 movzx ecx, BYTE PTR [rax] 000cb 48 ff c0 inc rax 000ce 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000d5 88 4c 24 30 mov BYTE PTR $T18[rsp], cl 000d9 eb 05 jmp SHORT $LN70@stbi__tga_ $LN72@stbi__tga_: ; 1082 : } ; 1083 : return 0; 000db c6 44 24 30 00 mov BYTE PTR $T18[rsp], 0 $LN70@stbi__tga_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 000e0 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000e7 73 0f jae SHORT $LN75@stbi__tga_ ; 1078 : return *s->img_buffer++; 000e9 0f b6 08 movzx ecx, BYTE PTR [rax] 000ec 48 ff c0 inc rax 000ef 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000f6 eb 25 jmp SHORT $LN74@stbi__tga_ $LN75@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 000f8 83 3e 00 cmp DWORD PTR [rsi], 0 000fb 74 1e je SHORT $LN76@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 000fd 48 8b cb mov rcx, rbx 00100 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00105 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0010c 0f b6 08 movzx ecx, BYTE PTR [rax] 0010f 48 ff c0 inc rax 00112 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00119 eb 02 jmp SHORT $LN74@stbi__tga_ $LN76@stbi__tga_: ; 1082 : } ; 1083 : return 0; 0011b 32 c9 xor cl, cl $LN74@stbi__tga_: ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); 0011d 0f b6 c1 movzx eax, cl ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); 00120 48 8b cb mov rcx, rbx 00123 89 44 24 44 mov DWORD PTR tv2782[rsp], eax 00127 8b e8 mov ebp, eax 00129 89 44 24 3c mov DWORD PTR tga_image_type$1$[rsp], eax 0012d e8 00 00 00 00 call stbi__get16le ; 5412 : int tga_palette_len = stbi__get16le(s); 00132 48 8b cb mov rcx, rbx 00135 4c 63 e0 movsxd r12, eax 00138 e8 00 00 00 00 call stbi__get16le ; 1077 : if (s->img_buffer < s->img_buffer_end) 0013d 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] ; 5412 : int tga_palette_len = stbi__get16le(s); 00144 89 44 24 58 mov DWORD PTR tga_palette_len$1$[rsp], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 00148 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 0014f 73 0f jae SHORT $LN79@stbi__tga_ ; 1078 : return *s->img_buffer++; 00151 0f b6 11 movzx edx, BYTE PTR [rcx] 00154 48 ff c1 inc rcx 00157 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 0015e eb 25 jmp SHORT $LN78@stbi__tga_ $LN79@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00160 83 3e 00 cmp DWORD PTR [rsi], 0 00163 74 1e je SHORT $LN80@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00165 48 8b cb mov rcx, rbx 00168 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0016d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00174 0f b6 10 movzx edx, BYTE PTR [rax] 00177 48 ff c0 inc rax 0017a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00181 eb 02 jmp SHORT $LN78@stbi__tga_ $LN80@stbi__tga_: ; 1082 : } ; 1083 : return 0; 00183 32 d2 xor dl, dl $LN78@stbi__tga_: ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); 00185 48 8b cb mov rcx, rbx 00188 0f b6 fa movzx edi, dl 0018b e8 00 00 00 00 call stbi__get16le ; 5415 : int tga_y_origin = stbi__get16le(s); 00190 48 8b cb mov rcx, rbx 00193 e8 00 00 00 00 call stbi__get16le ; 5416 : int tga_width = stbi__get16le(s); 00198 48 8b cb mov rcx, rbx 0019b e8 00 00 00 00 call stbi__get16le ; 5417 : int tga_height = stbi__get16le(s); 001a0 48 8b cb mov rcx, rbx 001a3 89 44 24 40 mov DWORD PTR tga_width$1$[rsp], eax 001a7 e8 00 00 00 00 call stbi__get16le 001ac 89 44 24 38 mov DWORD PTR $T19[rsp], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 001b0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001b7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 001be 73 0f jae SHORT $LN83@stbi__tga_ ; 1078 : return *s->img_buffer++; 001c0 0f b6 08 movzx ecx, BYTE PTR [rax] 001c3 48 ff c0 inc rax 001c6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001cd eb 25 jmp SHORT $LN82@stbi__tga_ $LN83@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 001cf 83 3e 00 cmp DWORD PTR [rsi], 0 001d2 74 1e je SHORT $LN84@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 001d4 48 8b cb mov rcx, rbx 001d7 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001dc 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001e3 0f b6 08 movzx ecx, BYTE PTR [rax] 001e6 48 ff c0 inc rax 001e9 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001f0 eb 02 jmp SHORT $LN82@stbi__tga_ $LN84@stbi__tga_: ; 1082 : } ; 1083 : return 0; 001f2 32 c9 xor cl, cl $LN82@stbi__tga_: ; 5418 : int tga_bits_per_pixel = stbi__get8(s); 001f4 0f b6 d1 movzx edx, cl 001f7 89 54 24 60 mov DWORD PTR tga_bits_per_pixel$1$[rsp], edx ; 1077 : if (s->img_buffer < s->img_buffer_end) 001fb 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00202 73 0f jae SHORT $LN87@stbi__tga_ ; 1078 : return *s->img_buffer++; 00204 0f b6 08 movzx ecx, BYTE PTR [rax] 00207 48 ff c0 inc rax 0020a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00211 eb 29 jmp SHORT $LN86@stbi__tga_ $LN87@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 00213 83 3e 00 cmp DWORD PTR [rsi], 0 00216 74 22 je SHORT $LN88@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00218 48 8b cb mov rcx, rbx 0021b e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00220 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00227 8b 54 24 60 mov edx, DWORD PTR tga_bits_per_pixel$1$[rsp] 0022b 0f b6 08 movzx ecx, BYTE PTR [rax] 0022e 48 ff c0 inc rax 00231 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00238 eb 02 jmp SHORT $LN86@stbi__tga_ $LN88@stbi__tga_: ; 1082 : } ; 1083 : return 0; 0023a 32 c9 xor cl, cl $LN86@stbi__tga_: ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0023c 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 00240 45 33 f6 xor r14d, r14d 00243 0f b6 c1 movzx eax, cl 00246 45 8b fe mov r15d, r14d 00249 4c 89 74 24 50 mov QWORD PTR tga_palette$1$[rsp], r14 0024e 44 89 b4 24 80 00 00 00 mov DWORD PTR raw_data$[rsp], r14d 00256 44 89 74 24 5c mov DWORD PTR RLE_repeating$1$[rsp], r14d 0025b 45 8d 6e 01 lea r13d, QWORD PTR [r14+1] 0025f 81 fe 00 00 00 01 cmp esi, 16777216 ; 01000000H 00265 0f 8f c1 07 00 00 jg $LN271@stbi__tga_ ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0026b 44 8b 44 24 40 mov r8d, DWORD PTR tga_width$1$[rsp] 00270 41 81 f8 00 00 00 01 cmp r8d, 16777216 ; 01000000H 00277 0f 8f af 07 00 00 jg $LN271@stbi__tga_ ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) 0027d 83 fd 08 cmp ebp, 8 00280 72 07 jb SHORT $LN31@stbi__tga_ ; 5439 : { ; 5440 : tga_image_type -= 8; 00282 83 ed 08 sub ebp, 8 00285 89 6c 24 3c mov DWORD PTR tga_image_type$1$[rsp], ebp $LN31@stbi__tga_: ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); 00289 c1 e8 05 shr eax, 5 0028c 41 8b cd mov ecx, r13d 0028f 41 23 c5 and eax, r13d ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); 00292 41 8b ee mov ebp, r14d 00295 2b c8 sub ecx, eax 00297 89 4c 24 64 mov DWORD PTR tga_inverted$1$[rsp], ecx 0029b 44 38 74 24 30 cmp BYTE PTR $T18[rsp], r14b 002a0 74 22 je SHORT $LN32@stbi__tga_ ; 5273 : switch (bits_per_pixel) { 002a2 8b cf mov ecx, edi 002a4 83 e9 08 sub ecx, 8 002a7 74 16 je SHORT $LN98@stbi__tga_ 002a9 83 e9 07 sub ecx, 7 002ac 74 67 je SHORT $LN113@stbi__tga_ 002ae 41 2b cd sub ecx, r13d 002b1 74 62 je SHORT $LN113@stbi__tga_ 002b3 83 e9 08 sub ecx, 8 002b6 74 29 je SHORT $LN103@stbi__tga_ 002b8 83 f9 08 cmp ecx, 8 002bb 75 2b jne SHORT $LN273@stbi__tga_ ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; 002bd eb 22 jmp SHORT $LN103@stbi__tga_ $LN98@stbi__tga_: ; 5274 : case 8: return STBI_grey; 002bf 41 8b fd mov edi, r13d ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); 002c2 eb 20 jmp SHORT $LN107@stbi__tga_ $LN32@stbi__tga_: ; 5273 : switch (bits_per_pixel) { 002c4 8b ca mov ecx, edx 002c6 83 e9 08 sub ecx, 8 002c9 74 54 je SHORT $LN111@stbi__tga_ 002cb 83 e9 07 sub ecx, 7 002ce 74 45 je SHORT $LN113@stbi__tga_ 002d0 41 2b cd sub ecx, r13d 002d3 74 32 je SHORT $LN112@stbi__tga_ 002d5 83 e9 08 sub ecx, 8 002d8 74 05 je SHORT $LN116@stbi__tga_ 002da 83 f9 08 cmp ecx, 8 002dd 75 09 jne SHORT $LN273@stbi__tga_ $LN116@stbi__tga_: ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; 002df 8b fa mov edi, edx $LN103@stbi__tga_: ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency 002e1 c1 ef 03 shr edi, 3 $LN107@stbi__tga_: 002e4 85 ff test edi, edi 002e6 75 3a jne SHORT $LN34@stbi__tga_ $LN273@stbi__tga_: ; 431 : stbi__g_failure_reason = str; 002e8 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 002ee 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 002f7 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 002fb 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@DMAPJJO@bad?5format@ ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); 00302 e9 3f 07 00 00 jmp $LN375@stbi__tga_ $LN112@stbi__tga_: ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); 00307 83 7c 24 3c 03 cmp DWORD PTR tga_image_type$1$[rsp], 3 ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; 0030c 75 07 jne SHORT $LN113@stbi__tga_ 0030e bf 02 00 00 00 mov edi, 2 00313 eb 0d jmp SHORT $LN34@stbi__tga_ $LN113@stbi__tga_: ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; 00315 41 8b ed mov ebp, r13d 00318 bf 03 00 00 00 mov edi, 3 0031d eb 03 jmp SHORT $LN34@stbi__tga_ $LN111@stbi__tga_: ; 5274 : case 8: return STBI_grey; 0031f 41 8b fd mov edi, r13d $LN34@stbi__tga_: ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; 00322 48 8b 44 24 68 mov rax, QWORD PTR x$GSCopy$1$[rsp] 00327 44 89 00 mov DWORD PTR [rax], r8d ; 5454 : *y = tga_height; 0032a 48 8b 44 24 48 mov rax, QWORD PTR y$GSCopy$1$[rsp] 0032f 89 30 mov DWORD PTR [rax], esi ; 5455 : if (comp) *comp = tga_comp; 00331 48 8b 44 24 78 mov rax, QWORD PTR comp$GSCopy$1$[rsp] 00336 48 85 c0 test rax, rax 00339 74 02 je SHORT $LN35@stbi__tga_ 0033b 89 38 mov DWORD PTR [rax], edi $LN35@stbi__tga_: ; 467 : if (a < 0 || b < 0) return 0; 0033d 45 85 c0 test r8d, r8d 00340 0f 88 e6 06 00 00 js $LN271@stbi__tga_ 00346 85 f6 test esi, esi 00348 0f 88 de 06 00 00 js $LN271@stbi__tga_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0034e 74 11 je SHORT $LN272@stbi__tga_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00350 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00355 99 cdq 00356 f7 fe idiv esi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00358 44 3b c0 cmp r8d, eax 0035b 0f 8f cb 06 00 00 jg $LN271@stbi__tga_ $LN272@stbi__tga_: 00361 8b ce mov ecx, esi 00363 41 0f af c8 imul ecx, r8d ; 467 : if (a < 0 || b < 0) return 0; 00367 85 c9 test ecx, ecx 00369 0f 88 bd 06 00 00 js $LN271@stbi__tga_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0036f 33 d2 xor edx, edx 00371 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00376 f7 f7 div edi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00378 3b c8 cmp ecx, eax 0037a 0f 8f ac 06 00 00 jg $LN271@stbi__tga_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00380 85 f6 test esi, esi 00382 74 11 je SHORT $LN274@stbi__tga_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00384 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00389 99 cdq 0038a f7 fe idiv esi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0038c 44 3b c0 cmp r8d, eax 0038f 0f 8f 7b 06 00 00 jg $LN264@stbi__tga_ $LN274@stbi__tga_: ; 509 : return stbi__malloc(a * b * c + add); 00395 8b c6 mov eax, esi 00397 0f af c7 imul eax, edi 0039a 41 0f af c0 imul eax, r8d 0039e 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 003a1 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 003a7 48 89 44 24 48 mov QWORD PTR tga_data$1$[rsp], rax 003ac 4c 8b c0 mov r8, rax ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); 003af 48 85 c0 test rax, rax 003b2 0f 84 58 06 00 00 je $LN264@stbi__tga_ ; 1107 : if (n == 0) return; // already there! 003b8 48 63 54 24 34 movsxd rdx, DWORD PTR tga_offset$1$[rsp] 003bd 85 d2 test edx, edx 003bf 74 3b je SHORT $LN167@stbi__tga_ ; 1111 : } ; 1112 : if (s->io.read) { 003c1 4c 39 73 10 cmp QWORD PTR [rbx+16], r14 003c5 74 2e je SHORT $LN171@stbi__tga_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 003c7 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 003cd 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 003d3 3b ca cmp ecx, edx 003d5 7d 1e jge SHORT $LN171@stbi__tga_ ; 1115 : s->img_buffer = s->img_buffer_end; 003d7 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 003de 2b d1 sub edx, ecx 003e0 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 003e4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003eb ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 003ee 4c 8b 44 24 48 mov r8, QWORD PTR tga_data$1$[rsp] 003f3 eb 07 jmp SHORT $LN167@stbi__tga_ $LN171@stbi__tga_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 003f5 48 01 93 c0 00 00 00 add QWORD PTR [rbx+192], rdx $LN167@stbi__tga_: ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { 003fc 44 38 74 24 30 cmp BYTE PTR $T18[rsp], r14b 00401 0f 85 bc 00 00 00 jne $LN263@stbi__tga_ 00407 8b 54 24 44 mov edx, DWORD PTR tv2782[rsp] 0040b 44 8b e7 mov r12d, edi 0040e 89 6c 24 3c mov DWORD PTR tga_rgb16$4$[rsp], ebp 00412 89 7c 24 34 mov DWORD PTR tga_comp$4$[rsp], edi 00416 83 fa 08 cmp edx, 8 00419 0f 83 58 02 00 00 jae $LN284@stbi__tga_ 0041f 89 6c 24 3c mov DWORD PTR tga_rgb16$4$[rsp], ebp 00423 89 7c 24 34 mov DWORD PTR tga_comp$4$[rsp], edi 00427 85 ed test ebp, ebp 00429 0f 85 48 02 00 00 jne $LN284@stbi__tga_ ; 5467 : for (i = 0; i < tga_height; ++i) { 0042f 44 8b ed mov r13d, ebp 00432 85 f6 test esi, esi 00434 0f 8e 59 05 00 00 jle $LN58@stbi__tga_ ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; 0043a 44 8b ff mov r15d, edi 0043d 44 0f af 7c 24 40 imul r15d, DWORD PTR tga_width$1$[rsp] 00443 44 39 74 24 64 cmp DWORD PTR tga_inverted$1$[rsp], r14d 00448 44 8b 74 24 38 mov r14d, DWORD PTR $T19[rsp] 0044d 74 44 je SHORT $LN62@stbi__tga_ 0044f 41 8b c7 mov eax, r15d 00452 f7 d8 neg eax 00454 4c 63 e0 movsxd r12, eax 00457 8d 46 ff lea eax, DWORD PTR [rsi-1] 0045a 0f af c7 imul eax, edi 0045d 0f af 44 24 40 imul eax, DWORD PTR tga_width$1$[rsp] 00462 48 63 f0 movsxd rsi, eax 00465 49 03 f0 add rsi, r8 00468 0f 1f 84 00 00 00 00 00 npad 8 $LL4@stbi__tga_: ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); 00470 45 8b c7 mov r8d, r15d 00473 48 8b d6 mov rdx, rsi 00476 48 8b cb mov rcx, rbx 00479 e8 00 00 00 00 call stbi__getn 0047e 49 03 f4 add rsi, r12 00481 49 83 ee 01 sub r14, 1 00485 75 e9 jne SHORT $LL4@stbi__tga_ ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; 00487 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 0048b 44 8b e7 mov r12d, edi 0048e e9 00 05 00 00 jmp $LN58@stbi__tga_ $LN62@stbi__tga_: ; 5467 : for (i = 0; i < tga_height; ++i) { 00493 4d 63 e7 movsxd r12, r15d 00496 49 8b f0 mov rsi, r8 00499 0f 1f 80 00 00 00 00 npad 7 $LL234@stbi__tga_: ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); 004a0 45 8b c7 mov r8d, r15d 004a3 48 8b d6 mov rdx, rsi 004a6 48 8b cb mov rcx, rbx 004a9 e8 00 00 00 00 call stbi__getn 004ae 49 03 f4 add rsi, r12 004b1 49 83 ee 01 sub r14, 1 004b5 75 e9 jne SHORT $LL234@stbi__tga_ ; 5471 : } ; 5472 : } 004b7 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 004bb 44 8b e7 mov r12d, edi 004be e9 d0 04 00 00 jmp $LN58@stbi__tga_ $LN263@stbi__tga_: ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ 004c3 44 39 74 24 58 cmp DWORD PTR tga_palette_len$1$[rsp], r14d 004c8 75 28 jne SHORT $LN41@stbi__tga_ ; 5478 : STBI_FREE(tga_data); 004ca 49 8b c8 mov rcx, r8 $LN376@stbi__tga_: ; 5613 : } 004cd ff 15 00 00 00 00 call QWORD PTR __imp_free 004d3 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 004d9 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 004e2 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 004e6 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0M@ILLOCNCO@bad?5palette@ 004ed e9 54 05 00 00 jmp $LN375@stbi__tga_ $LN41@stbi__tga_: ; 1107 : if (n == 0) return; // already there! 004f2 45 85 e4 test r12d, r12d 004f5 74 4d je SHORT $LN189@stbi__tga_ ; 1108 : if (n < 0) { 004f7 79 10 jns SHORT $LN191@stbi__tga_ ; 1109 : s->img_buffer = s->img_buffer_end; 004f9 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00500 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 1110 : return; 00507 eb 3b jmp SHORT $LN189@stbi__tga_ $LN191@stbi__tga_: ; 1111 : } ; 1112 : if (s->io.read) { 00509 4c 39 73 10 cmp QWORD PTR [rbx+16], r14 0050d 74 2e je SHORT $LN193@stbi__tga_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 0050f 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 00515 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 0051b 41 3b cc cmp ecx, r12d 0051e 7d 1d jge SHORT $LN193@stbi__tga_ ; 1115 : s->img_buffer = s->img_buffer_end; 00520 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00527 44 2b e1 sub r12d, ecx 0052a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0052e 41 8b d4 mov edx, r12d 00531 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00538 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 0053b eb 07 jmp SHORT $LN189@stbi__tga_ $LN193@stbi__tga_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0053d 4c 01 a3 c0 00 00 00 add QWORD PTR [rbx+192], r12 $LN189@stbi__tga_: ; 467 : if (a < 0 || b < 0) return 0; 00544 44 8b 64 24 58 mov r12d, DWORD PTR tga_palette_len$1$[rsp] 00549 45 85 e4 test r12d, r12d 0054c 0f 88 b3 04 00 00 js $LN265@stbi__tga_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00552 33 d2 xor edx, edx 00554 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00559 f7 f7 div edi ; 477 : return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a * b, add); 0055b 44 3b e0 cmp r12d, eax 0055e 0f 8f a1 04 00 00 jg $LN265@stbi__tga_ ; 502 : return stbi__malloc(a * b + add); 00564 8b f7 mov esi, edi 00566 41 0f af f4 imul esi, r12d 0056a 48 63 ce movsxd rcx, esi ; 438 : return STBI_MALLOC(size); 0056d ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00573 48 89 44 24 50 mov QWORD PTR tga_palette$1$[rsp], rax ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { 00578 48 85 c0 test rax, rax 0057b 0f 84 84 04 00 00 je $LN265@stbi__tga_ ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { 00581 89 6c 24 3c mov DWORD PTR tga_rgb16$4$[rsp], ebp 00585 89 7c 24 34 mov DWORD PTR tga_comp$4$[rsp], edi 00589 85 ed test ebp, ebp 0058b 0f 84 b1 00 00 00 je $LN43@stbi__tga_ ; 5491 : stbi_uc* pal_entry = tga_palette; 00591 48 8b f0 mov rsi, rax ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { 00594 45 85 e4 test r12d, r12d 00597 0f 8e 95 00 00 00 jle $LN267@stbi__tga_ 0059d 0f 1f 00 npad 3 $LL7@stbi__tga_: ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); 005a0 48 8b cb mov rcx, rbx 005a3 e8 00 00 00 00 call stbi__get16le ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; 005a8 44 0f b7 c0 movzx r8d, ax 005ac 41 8b c0 mov eax, r8d 005af c1 e8 0a shr eax, 10 005b2 83 e0 1f and eax, 31 ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); 005b5 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 005bb b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 005c0 f7 e9 imul ecx 005c2 03 d1 add edx, ecx 005c4 c1 fa 04 sar edx, 4 005c7 8b c2 mov eax, edx 005c9 c1 e8 1f shr eax, 31 005cc 03 d0 add edx, eax 005ce 41 8b c0 mov eax, r8d 005d1 c1 e8 05 shr eax, 5 005d4 41 83 e0 1f and r8d, 31 005d8 83 e0 1f and eax, 31 005db 88 16 mov BYTE PTR [rsi], dl ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); 005dd 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 005e3 b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 005e8 f7 e9 imul ecx 005ea 03 d1 add edx, ecx ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); 005ec 41 69 c8 ff 00 00 00 imul ecx, r8d, 255 ; 000000ffH 005f3 c1 fa 04 sar edx, 4 005f6 8b c2 mov eax, edx 005f8 c1 e8 1f shr eax, 31 005fb 03 d0 add edx, eax 005fd b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 00602 88 56 01 mov BYTE PTR [rsi+1], dl 00605 f7 e9 imul ecx 00607 03 d1 add edx, ecx 00609 c1 fa 04 sar edx, 4 0060c 8b c2 mov eax, edx 0060e c1 e8 1f shr eax, 31 00611 03 d0 add edx, eax 00613 88 56 02 mov BYTE PTR [rsi+2], dl ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; 00616 48 03 f7 add rsi, rdi 00619 4d 2b e5 sub r12, r13 0061c 75 82 jne SHORT $LL7@stbi__tga_ 0061e 44 8b 64 24 34 mov r12d, DWORD PTR tga_comp$4$[rsp] 00623 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 00627 48 8b 7c 24 50 mov rdi, QWORD PTR tga_palette$1$[rsp] 0062c 8b 54 24 44 mov edx, DWORD PTR tv2782[rsp] 00630 eb 48 jmp SHORT $LN45@stbi__tga_ $LN267@stbi__tga_: ; 5496 : } ; 5497 : } 00632 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 00636 44 8b e7 mov r12d, edi 00639 8b 54 24 44 mov edx, DWORD PTR tv2782[rsp] 0063d 48 8b f8 mov rdi, rax 00640 eb 38 jmp SHORT $LN45@stbi__tga_ $LN43@stbi__tga_: ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { 00642 44 8b e7 mov r12d, edi 00645 44 8b c6 mov r8d, esi 00648 48 8b d0 mov rdx, rax 0064b 48 8b cb mov rcx, rbx 0064e 48 8b f8 mov rdi, rax 00651 e8 00 00 00 00 call stbi__getn 00656 85 c0 test eax, eax 00658 75 13 jne SHORT $LN279@stbi__tga_ ; 5499 : STBI_FREE(tga_data); 0065a 48 8b 4c 24 48 mov rcx, QWORD PTR tga_data$1$[rsp] 0065f ff 15 00 00 00 00 call QWORD PTR __imp_free ; 5500 : STBI_FREE(tga_palette); 00665 48 8b cf mov rcx, rdi ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); 00668 e9 60 fe ff ff jmp $LN376@stbi__tga_ $LN279@stbi__tga_: ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { 0066d 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 00671 8b 54 24 44 mov edx, DWORD PTR tv2782[rsp] 00675 eb 03 jmp SHORT $LN45@stbi__tga_ $LN284@stbi__tga_: ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) 00677 49 8b fe mov rdi, r14 $LN45@stbi__tga_: 0067a 8b 4c 24 40 mov ecx, DWORD PTR tga_width$1$[rsp] 0067e 8b c6 mov eax, esi 00680 0f af c1 imul eax, ecx ; 5540 : for (j = 0; j < tga_comp; ++j) { 00683 41 8b f4 mov esi, r12d 00686 85 c0 test eax, eax 00688 0f 84 76 02 00 00 je $LN9@stbi__tga_ ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) 0068e 48 8b 6c 24 48 mov rbp, QWORD PTR tga_data$1$[rsp] 00693 4c 8d 84 24 80 00 00 00 lea r8, QWORD PTR raw_data$[rsp] 0069b 49 2b e8 sub rbp, r8 0069e 49 63 cc movsxd rcx, r12d 006a1 48 89 44 24 68 mov QWORD PTR tv2753[rsp], rax $LL10@stbi__tga_: ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) 006a6 83 fa 08 cmp edx, 8 006a9 72 70 jb SHORT $LN266@stbi__tga_ ; 5509 : { ; 5510 : if (RLE_count == 0) 006ab 45 85 ff test r15d, r15d 006ae 75 5b jne SHORT $LN48@stbi__tga_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 006b0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006b7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 006be 73 0f jae SHORT $LN176@stbi__tga_ ; 1078 : return *s->img_buffer++; 006c0 0f b6 08 movzx ecx, BYTE PTR [rax] 006c3 48 ff c0 inc rax 006c6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 006cd eb 26 jmp SHORT $LN175@stbi__tga_ $LN176@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 006cf 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 006d3 74 1e je SHORT $LN177@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 006d5 48 8b cb mov rcx, rbx 006d8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 006dd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 006e4 0f b6 08 movzx ecx, BYTE PTR [rax] 006e7 48 ff c0 inc rax 006ea 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 006f1 eb 02 jmp SHORT $LN175@stbi__tga_ $LN177@stbi__tga_: ; 1082 : } ; 1083 : return 0; 006f3 32 c9 xor cl, cl $LN175@stbi__tga_: ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); 006f5 0f b6 c1 movzx eax, cl ; 5514 : RLE_count = 1 + (RLE_cmd & 127); 006f8 44 8b f8 mov r15d, eax 006fb 41 83 e7 7f and r15d, 127 ; 0000007fH 006ff 41 ff c7 inc r15d ; 5515 : RLE_repeating = RLE_cmd >> 7; 00702 c1 e8 07 shr eax, 7 00705 89 44 24 5c mov DWORD PTR RLE_repeating$1$[rsp], eax ; 5516 : read_next_pixel = 1; ; 5517 : } 00709 eb 10 jmp SHORT $LN266@stbi__tga_ $LN48@stbi__tga_: ; 5518 : else if (!RLE_repeating) 0070b 44 39 74 24 5c cmp DWORD PTR RLE_repeating$1$[rsp], r14d 00710 74 09 je SHORT $LN266@stbi__tga_ ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) 00712 45 85 ed test r13d, r13d 00715 0f 84 94 01 00 00 je $LN51@stbi__tga_ $LN266@stbi__tga_: ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) 0071b 44 38 74 24 30 cmp BYTE PTR $T18[rsp], r14b 00720 0f 84 91 00 00 00 je $LN52@stbi__tga_ ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); 00726 83 7c 24 60 08 cmp DWORD PTR tga_bits_per_pixel$1$[rsp], 8 0072b 75 50 jne SHORT $LN64@stbi__tga_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0072d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00734 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0073b 73 12 jae SHORT $LN180@stbi__tga_ ; 1078 : return *s->img_buffer++; 0073d 0f b6 08 movzx ecx, BYTE PTR [rax] 00740 48 ff c0 inc rax 00743 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); 0074a 0f b6 c1 movzx eax, cl 0074d eb 36 jmp SHORT $LN65@stbi__tga_ $LN180@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 0074f 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 00753 74 21 je SHORT $LN181@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00755 48 8b cb mov rcx, rbx 00758 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0075d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00764 0f b6 08 movzx ecx, BYTE PTR [rax] 00767 48 ff c0 inc rax 0076a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); 00771 0f b6 c1 movzx eax, cl 00774 eb 0f jmp SHORT $LN65@stbi__tga_ $LN181@stbi__tga_: ; 1083 : return 0; 00776 32 c9 xor cl, cl ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); 00778 0f b6 c1 movzx eax, cl 0077b eb 08 jmp SHORT $LN65@stbi__tga_ $LN64@stbi__tga_: 0077d 48 8b cb mov rcx, rbx 00780 e8 00 00 00 00 call stbi__get16le $LN65@stbi__tga_: ; 5540 : for (j = 0; j < tga_comp; ++j) { 00785 45 85 e4 test r12d, r12d 00788 0f 84 16 01 00 00 je $LN15@stbi__tga_ ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; 0078e 3b 44 24 58 cmp eax, DWORD PTR tga_palette_len$1$[rsp] 00792 41 8b ce mov ecx, r14d 00795 4c 8b c6 mov r8, rsi 00798 0f 4c c8 cmovl ecx, eax 0079b 41 0f af cc imul ecx, r12d 0079f 48 63 d1 movsxd rdx, ecx 007a2 48 8d 8c 24 80 00 00 00 lea rcx, QWORD PTR raw_data$[rsp] 007aa 48 03 d7 add rdx, rdi 007ad e8 00 00 00 00 call memcpy ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } 007b2 e9 ed 00 00 00 jmp $LN15@stbi__tga_ $LN52@stbi__tga_: ; 5544 : else if (tga_rgb16) { 007b7 44 39 74 24 3c cmp DWORD PTR tga_rgb16$4$[rsp], r14d 007bc 0f 84 85 00 00 00 je $LN55@stbi__tga_ ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); 007c2 48 8b cb mov rcx, rbx 007c5 e8 00 00 00 00 call stbi__get16le ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; 007ca 44 0f b7 c0 movzx r8d, ax 007ce 41 8b c0 mov eax, r8d 007d1 c1 e8 0a shr eax, 10 007d4 83 e0 1f and eax, 31 ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); 007d7 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 007dd b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 007e2 f7 e9 imul ecx 007e4 03 d1 add edx, ecx 007e6 c1 fa 04 sar edx, 4 007e9 8b c2 mov eax, edx 007eb c1 e8 1f shr eax, 31 007ee 03 d0 add edx, eax 007f0 41 8b c0 mov eax, r8d 007f3 c1 e8 05 shr eax, 5 007f6 41 83 e0 1f and r8d, 31 007fa 83 e0 1f and eax, 31 007fd 88 94 24 80 00 00 00 mov BYTE PTR raw_data$[rsp], dl ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); 00804 69 c8 ff 00 00 00 imul ecx, eax, 255 ; 000000ffH 0080a b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 0080f f7 e9 imul ecx 00811 03 d1 add edx, ecx ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); 00813 41 69 c8 ff 00 00 00 imul ecx, r8d, 255 ; 000000ffH 0081a c1 fa 04 sar edx, 4 0081d 8b c2 mov eax, edx 0081f c1 e8 1f shr eax, 31 00822 03 d0 add edx, eax 00824 b8 43 08 21 84 mov eax, -2078209981 ; ffffffff84210843H 00829 88 94 24 81 00 00 00 mov BYTE PTR raw_data$[rsp+1], dl 00830 f7 e9 imul ecx 00832 03 d1 add edx, ecx 00834 c1 fa 04 sar edx, 4 00837 8b c2 mov eax, edx 00839 c1 e8 1f shr eax, 31 0083c 03 d0 add edx, eax 0083e 88 94 24 82 00 00 00 mov BYTE PTR raw_data$[rsp+2], dl ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } 00845 eb 5d jmp SHORT $LN15@stbi__tga_ $LN55@stbi__tga_: ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { 00847 49 8b fe mov rdi, r14 0084a 45 85 e4 test r12d, r12d 0084d 74 55 je SHORT $LN15@stbi__tga_ 0084f 90 npad 1 $LL16@stbi__tga_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00850 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00857 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0085e 73 0f jae SHORT $LN140@stbi__tga_ ; 1078 : return *s->img_buffer++; 00860 0f b6 08 movzx ecx, BYTE PTR [rax] 00863 48 ff c0 inc rax 00866 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0086d eb 26 jmp SHORT $LN139@stbi__tga_ $LN140@stbi__tga_: ; 1079 : if (s->read_from_callbacks) { 0086f 44 39 73 30 cmp DWORD PTR [rbx+48], r14d 00873 74 1e je SHORT $LN141@stbi__tga_ ; 1080 : stbi__refill_buffer(s); 00875 48 8b cb mov rcx, rbx 00878 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0087d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00884 0f b6 08 movzx ecx, BYTE PTR [rax] 00887 48 ff c0 inc rax 0088a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00891 eb 02 jmp SHORT $LN139@stbi__tga_ $LN141@stbi__tga_: ; 1082 : } ; 1083 : return 0; 00893 32 c9 xor cl, cl $LN139@stbi__tga_: ; 5551 : raw_data[j] = stbi__get8(s); 00895 88 8c 3c 80 00 00 00 mov BYTE PTR raw_data$[rsp+rdi], cl 0089c 48 ff c7 inc rdi 0089f 48 3b fe cmp rdi, rsi 008a2 7c ac jl SHORT $LL16@stbi__tga_ $LN15@stbi__tga_: 008a4 48 8b 44 24 68 mov rax, QWORD PTR tv2753[rsp] ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; 008a9 45 8b ee mov r13d, r14d 008ac 49 63 cc movsxd rcx, r12d $LN51@stbi__tga_: ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) 008af 49 8b fe mov rdi, r14 008b2 45 85 e4 test r12d, r12d 008b5 74 2b je SHORT $LN18@stbi__tga_ ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; 008b7 48 8d 8c 24 80 00 00 00 lea rcx, QWORD PTR raw_data$[rsp] 008bf 4c 8b c6 mov r8, rsi 008c2 48 03 cd add rcx, rbp 008c5 48 8d 94 24 80 00 00 00 lea rdx, QWORD PTR raw_data$[rsp] 008cd e8 00 00 00 00 call memcpy $LL237@stbi__tga_: ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) 008d2 48 ff c7 inc rdi 008d5 48 3b fe cmp rdi, rsi 008d8 7c f8 jl SHORT $LL237@stbi__tga_ 008da 48 8b 44 24 68 mov rax, QWORD PTR tv2753[rsp] 008df 49 63 cc movsxd rcx, r12d $LN18@stbi__tga_: ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) 008e2 48 8b 7c 24 50 mov rdi, QWORD PTR tga_palette$1$[rsp] ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; 008e7 41 ff cf dec r15d 008ea 8b 54 24 44 mov edx, DWORD PTR tv2782[rsp] 008ee 48 03 e9 add rbp, rcx 008f1 48 83 e8 01 sub rax, 1 008f5 48 89 44 24 68 mov QWORD PTR tv2753[rsp], rax 008fa 0f 85 a6 fd ff ff jne $LL10@stbi__tga_ 00900 8b 4c 24 40 mov ecx, DWORD PTR tga_width$1$[rsp] $LN9@stbi__tga_: ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) 00904 8b 74 24 38 mov esi, DWORD PTR $T19[rsp] 00908 44 39 74 24 64 cmp DWORD PTR tga_inverted$1$[rsp], r14d 0090d 74 6f je SHORT $LN21@stbi__tga_ ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) 0090f 85 f6 test esi, esi 00911 7e 6b jle SHORT $LN21@stbi__tga_ 00913 45 8b dc mov r11d, r12d 00916 44 8d 56 ff lea r10d, DWORD PTR [rsi-1] 0091a 45 0f af d4 imul r10d, r12d 0091e 41 8b de mov ebx, r14d 00921 4c 8b 64 24 48 mov r12, QWORD PTR tga_data$1$[rsp] 00926 44 0f af d9 imul r11d, ecx 0092a 44 0f af d1 imul r10d, ecx 0092e 66 90 npad 2 $LL22@stbi__tga_: ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; 00930 45 8b c3 mov r8d, r11d ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) 00933 45 85 db test r11d, r11d 00936 7e 32 jle SHORT $LN20@stbi__tga_ ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; 00938 48 63 c3 movsxd rax, ebx 0093b 4d 63 ca movsxd r9, r10d 0093e 4c 2b c8 sub r9, rax 00941 4a 8d 14 20 lea rdx, QWORD PTR [rax+r12] 00945 66 66 66 0f 1f 84 00 00 00 00 00 npad 11 $LL25@stbi__tga_: ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; 00950 42 0f b6 04 0a movzx eax, BYTE PTR [rdx+r9] 00955 41 ff c8 dec r8d 00958 0f b6 0a movzx ecx, BYTE PTR [rdx] 0095b 88 02 mov BYTE PTR [rdx], al ; 5576 : tga_data[index2] = temp; 0095d 42 88 0c 0a mov BYTE PTR [rdx+r9], cl ; 5577 : ++index1; 00961 48 8d 52 01 lea rdx, QWORD PTR [rdx+1] 00965 45 85 c0 test r8d, r8d 00968 7f e6 jg SHORT $LL25@stbi__tga_ $LN20@stbi__tga_: ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) 0096a 41 03 db add ebx, r11d 0096d 45 2b d3 sub r10d, r11d 00970 41 83 c6 02 add r14d, 2 00974 44 3b f6 cmp r14d, esi 00977 7c b7 jl SHORT $LL22@stbi__tga_ 00979 44 8b 64 24 34 mov r12d, DWORD PTR tga_comp$4$[rsp] $LN21@stbi__tga_: ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) 0097e 48 8b 4c 24 50 mov rcx, QWORD PTR tga_palette$1$[rsp] 00983 48 85 c9 test rcx, rcx 00986 74 06 je SHORT $LN282@stbi__tga_ ; 5584 : { ; 5585 : STBI_FREE(tga_palette); 00988 ff 15 00 00 00 00 call QWORD PTR __imp_free $LN282@stbi__tga_: ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) 0098e 44 8b 6c 24 3c mov r13d, DWORD PTR tga_rgb16$4$[rsp] $LN58@stbi__tga_: 00993 48 8b 4c 24 48 mov rcx, QWORD PTR tga_data$1$[rsp] 00998 8b 54 24 40 mov edx, DWORD PTR tga_width$1$[rsp] 0099c 41 83 fc 03 cmp r12d, 3 009a0 72 3c jb SHORT $LN27@stbi__tga_ 009a2 45 85 ed test r13d, r13d 009a5 75 37 jne SHORT $LN27@stbi__tga_ ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) 009a7 8b c6 mov eax, esi 009a9 4c 8b d1 mov r10, rcx 009ac 0f af c2 imul eax, edx 009af 85 c0 test eax, eax 009b1 74 2b je SHORT $LN27@stbi__tga_ ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; 009b3 41 8b dc mov ebx, r12d 009b6 44 8b d8 mov r11d, eax 009b9 0f 1f 80 00 00 00 00 npad 7 $LL28@stbi__tga_: ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; 009c0 41 0f b6 0a movzx ecx, BYTE PTR [r10] ; 5596 : tga_pixel[0] = tga_pixel[2]; 009c4 41 0f b6 42 02 movzx eax, BYTE PTR [r10+2] 009c9 41 88 02 mov BYTE PTR [r10], al ; 5597 : tga_pixel[2] = temp; 009cc 41 88 4a 02 mov BYTE PTR [r10+2], cl ; 5598 : tga_pixel += tga_comp; 009d0 4c 03 d3 add r10, rbx 009d3 49 83 eb 01 sub r11, 1 009d7 75 e7 jne SHORT $LL28@stbi__tga_ ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) 009d9 48 8b 4c 24 48 mov rcx, QWORD PTR tga_data$1$[rsp] $LN27@stbi__tga_: ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) 009de 8b 44 24 70 mov eax, DWORD PTR req_comp$GSCopy$1$[rsp] 009e2 85 c0 test eax, eax 009e4 74 1a je SHORT $LN60@stbi__tga_ 009e6 41 3b c4 cmp eax, r12d 009e9 74 15 je SHORT $LN60@stbi__tga_ ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); 009eb 44 8b ca mov r9d, edx 009ee 89 74 24 20 mov DWORD PTR [rsp+32], esi 009f2 41 8b d4 mov edx, r12d 009f5 44 8b c0 mov r8d, eax 009f8 e8 00 00 00 00 call stbi__convert_format 009fd 48 8b c8 mov rcx, rax $LN60@stbi__tga_: ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; 00a00 48 8b c1 mov rax, rcx 00a03 eb 4c jmp SHORT $LN1@stbi__tga_ $LN265@stbi__tga_: ; 5487 : STBI_FREE(tga_data); 00a05 48 8b 4c 24 48 mov rcx, QWORD PTR tga_data$1$[rsp] 00a0a ff 15 00 00 00 00 call QWORD PTR __imp_free $LN264@stbi__tga_: ; 5613 : } 00a10 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00a16 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00a1f 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00a23 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00a2a eb 1a jmp SHORT $LN375@stbi__tga_ $LN271@stbi__tga_: 00a2c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00a32 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00a3b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00a3f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ $LN375@stbi__tga_: 00a46 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00a4b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00a4f 33 c0 xor eax, eax $LN1@stbi__tga_: 00a51 48 8b 8c 24 88 00 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 00a59 48 33 cc xor rcx, rsp 00a5c e8 00 00 00 00 call __security_check_cookie 00a61 48 81 c4 98 00 00 00 add rsp, 152 ; 00000098H 00a68 41 5f pop r15 00a6a 41 5e pop r14 00a6c 41 5d pop r13 00a6e 41 5c pop r12 00a70 5f pop rdi 00a71 5e pop rsi 00a72 5d pop rbp 00a73 5b pop rbx 00a74 c3 ret 0 stbi__tga_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__psd_test _TEXT SEGMENT s$ = 48 stbi__psd_test PROC ; COMDAT ; 5621 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H 0000a 48 8b f9 mov rdi, rcx ; 1168 : stbi__uint32 z = stbi__get16be(s); 0000d e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00012 48 8b cf mov rcx, rdi 00015 8b d8 mov ebx, eax 00017 e8 00 00 00 00 call stbi__get16be ; 342 : s->img_buffer = s->img_buffer_original; 0001c 48 8b 8f d0 00 00 00 mov rcx, QWORD PTR [rdi+208] ; 5622 : int r = (stbi__get32be(s) == 0x38425053); 00023 33 d2 xor edx, edx ; 1169 : return (z << 16) + stbi__get16be(s); 00025 c1 e3 10 shl ebx, 16 00028 03 c3 add eax, ebx ; 342 : s->img_buffer = s->img_buffer_original; 0002a 48 89 8f c0 00 00 00 mov QWORD PTR [rdi+192], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00031 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] ; 5622 : int r = (stbi__get32be(s) == 0x38425053); 00038 3d 53 50 42 38 cmp eax, 943870035 ; 38425053H ; 5625 : } 0003d 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00042 0f 94 c2 sete dl ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00045 48 89 8f c8 00 00 00 mov QWORD PTR [rdi+200], rcx ; 5623 : stbi__rewind(s); ; 5624 : return r; 0004c 8b c2 mov eax, edx ; 5625 : } 0004e 48 83 c4 20 add rsp, 32 ; 00000020H 00052 5f pop rdi 00053 c3 ret 0 stbi__psd_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__psd_decode_rle _TEXT SEGMENT s$ = 64 p$ = 72 pixelCount$ = 80 stbi__psd_decode_rle PROC ; COMDAT ; 5628 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 20 sub rsp, 32 ; 00000020H ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; 0001e 45 33 ff xor r15d, r15d 00021 45 8b e0 mov r12d, r8d 00024 48 8b fa mov rdi, rdx 00027 48 8b d9 mov rbx, rcx ; 5632 : while ((nleft = pixelCount - count) > 0) { 0002a 45 8b f0 mov r14d, r8d 0002d 45 85 c0 test r8d, r8d 00030 0f 8e 44 01 00 00 jle $LN41@stbi__psd_ 00036 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL2@stbi__psd_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00040 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00047 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0004e 73 0f jae SHORT $LN17@stbi__psd_ ; 1078 : return *s->img_buffer++; 00050 0f b6 08 movzx ecx, BYTE PTR [rax] 00053 48 ff c0 inc rax 00056 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0005d eb 26 jmp SHORT $LN16@stbi__psd_ $LN17@stbi__psd_: ; 1079 : if (s->read_from_callbacks) { 0005f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00063 74 1e je SHORT $LN18@stbi__psd_ ; 1080 : stbi__refill_buffer(s); 00065 48 8b cb mov rcx, rbx 00068 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0006d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00074 0f b6 08 movzx ecx, BYTE PTR [rax] 00077 48 ff c0 inc rax 0007a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00081 eb 02 jmp SHORT $LN16@stbi__psd_ $LN18@stbi__psd_: ; 1082 : } ; 1083 : return 0; 00083 32 c9 xor cl, cl $LN16@stbi__psd_: ; 5633 : len = stbi__get8(s); 00085 0f b6 e9 movzx ebp, cl ; 5634 : if (len == 128) { 00088 81 fd 80 00 00 00 cmp ebp, 128 ; 00000080H 0008e 0f 84 d7 00 00 00 je $LN7@stbi__psd_ ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { 00094 73 6c jae SHORT $LN10@stbi__psd_ ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; 00096 ff c5 inc ebp ; 5640 : if (len > nleft) return 0; // corrupt data 00098 41 3b ee cmp ebp, r14d 0009b 0f 87 fd 00 00 00 ja $LN32@stbi__psd_ ; 5641 : count += len; 000a1 44 03 fd add r15d, ebp 000a4 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__psd_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 000b0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000b7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000be 73 0f jae SHORT $LN21@stbi__psd_ ; 1078 : return *s->img_buffer++; 000c0 0f b6 08 movzx ecx, BYTE PTR [rax] 000c3 48 ff c0 inc rax 000c6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000cd eb 26 jmp SHORT $LN20@stbi__psd_ $LN21@stbi__psd_: ; 1079 : if (s->read_from_callbacks) { 000cf 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000d3 74 1e je SHORT $LN22@stbi__psd_ ; 1080 : stbi__refill_buffer(s); 000d5 48 8b cb mov rcx, rbx 000d8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000dd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000e4 0f b6 08 movzx ecx, BYTE PTR [rax] 000e7 48 ff c0 inc rax 000ea 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000f1 eb 02 jmp SHORT $LN20@stbi__psd_ $LN22@stbi__psd_: ; 1082 : } ; 1083 : return 0; 000f3 32 c9 xor cl, cl $LN20@stbi__psd_: ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); 000f5 88 0f mov BYTE PTR [rdi], cl ; 5644 : p += 4; 000f7 48 83 c7 04 add rdi, 4 ; 5645 : len--; 000fb 83 ed 01 sub ebp, 1 000fe 75 b0 jne SHORT $LL4@stbi__psd_ ; 5646 : } ; 5647 : } 00100 eb 69 jmp SHORT $LN7@stbi__psd_ $LN10@stbi__psd_: ; 5648 : else if (len > 128) { 00102 76 67 jbe SHORT $LN7@stbi__psd_ ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; 00104 be 01 01 00 00 mov esi, 257 ; 00000101H 00109 2b f5 sub esi, ebp ; 5653 : if (len > nleft) return 0; // corrupt data 0010b 41 3b f6 cmp esi, r14d 0010e 0f 8f 8a 00 00 00 jg $LN32@stbi__psd_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00114 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0011b 73 0f jae SHORT $LN25@stbi__psd_ ; 1078 : return *s->img_buffer++; 0011d 0f b6 08 movzx ecx, BYTE PTR [rax] 00120 48 ff c0 inc rax 00123 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0012a eb 26 jmp SHORT $LN24@stbi__psd_ $LN25@stbi__psd_: ; 1079 : if (s->read_from_callbacks) { 0012c 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00130 74 1e je SHORT $LN26@stbi__psd_ ; 1080 : stbi__refill_buffer(s); 00132 48 8b cb mov rcx, rbx 00135 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0013a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00141 0f b6 08 movzx ecx, BYTE PTR [rax] 00144 48 ff c0 inc rax 00147 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0014e eb 02 jmp SHORT $LN24@stbi__psd_ $LN26@stbi__psd_: ; 1082 : } ; 1083 : return 0; 00150 32 c9 xor cl, cl $LN24@stbi__psd_: ; 5654 : val = stbi__get8(s); ; 5655 : count += len; 00152 44 03 fe add r15d, esi ; 5656 : while (len) { 00155 85 f6 test esi, esi 00157 74 12 je SHORT $LN7@stbi__psd_ 00159 0f 1f 80 00 00 00 00 npad 7 $LL6@stbi__psd_: ; 5657 : *p = val; 00160 88 0f mov BYTE PTR [rdi], cl ; 5658 : p += 4; 00162 48 83 c7 04 add rdi, 4 ; 5659 : len--; 00166 83 ee 01 sub esi, 1 00169 75 f5 jne SHORT $LL6@stbi__psd_ $LN7@stbi__psd_: ; 5632 : while ((nleft = pixelCount - count) > 0) { 0016b 45 8b f4 mov r14d, r12d 0016e 45 2b f7 sub r14d, r15d 00171 45 85 f6 test r14d, r14d 00174 0f 8f c6 fe ff ff jg $LL2@stbi__psd_ $LN41@stbi__psd_: ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; 0017a b8 01 00 00 00 mov eax, 1 $LN1@stbi__psd_: ; 5665 : } 0017f 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 00184 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 00189 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 0018e 48 8b 7c 24 58 mov rdi, QWORD PTR [rsp+88] 00193 48 83 c4 20 add rsp, 32 ; 00000020H 00197 41 5f pop r15 00199 41 5e pop r14 0019b 41 5c pop r12 0019d c3 ret 0 $LN32@stbi__psd_: ; 5653 : if (len > nleft) return 0; // corrupt data 0019e 33 c0 xor eax, eax 001a0 eb dd jmp SHORT $LN1@stbi__psd_ stbi__psd_decode_rle ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__psd_load _TEXT SEGMENT bitdepth$1$ = 48 $T8 = 52 $T9 = 56 out$1$ = 64 s$ = 144 x$ = 152 y$ = 160 comp$ = 168 req_comp$ = 176 ri$ = 184 channelCount$1$ = 192 bpc$dead$ = 192 stbi__psd_load PROC ; COMDAT ; 5668 : { 00000 4c 89 4c 24 20 mov QWORD PTR [rsp+32], r9 00005 4c 89 44 24 18 mov QWORD PTR [rsp+24], r8 0000a 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx 0000f 53 push rbx 00010 57 push rdi 00011 48 83 ec 78 sub rsp, 120 ; 00000078H 00015 48 8b f9 mov rdi, rcx ; 1168 : stbi__uint32 z = stbi__get16be(s); 00018 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 0001d 48 8b cf mov rcx, rdi 00020 8b d8 mov ebx, eax 00022 e8 00 00 00 00 call stbi__get16be 00027 c1 e3 10 shl ebx, 16 0002a 03 c3 add eax, ebx ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" 0002c 3d 53 50 42 38 cmp eax, 943870035 ; 38425053H 00031 74 2c je SHORT $LN32@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 00033 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00039 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00042 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00047 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0004b 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07ECNCNLIK@not?5PSD@ 00052 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); 00056 33 c0 xor eax, eax ; 5873 : } 00058 48 83 c4 78 add rsp, 120 ; 00000078H 0005c 5f pop rdi 0005d 5b pop rbx 0005e c3 ret 0 $LN32@stbi__psd_: ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) 0005f 48 8b cf mov rcx, rdi 00062 e8 00 00 00 00 call stbi__get16be 00067 83 f8 01 cmp eax, 1 0006a 74 2c je SHORT $LN33@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 0006c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00072 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0007b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00080 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00084 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@CHBCDKKC@wrong?5version@ 0008b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); 0008f 33 c0 xor eax, eax ; 5873 : } 00091 48 83 c4 78 add rsp, 120 ; 00000078H 00095 5f pop rdi 00096 5b pop rbx 00097 c3 ret 0 $LN33@stbi__psd_: ; 1112 : if (s->io.read) { 00098 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 0009d 48 89 74 24 70 mov QWORD PTR [rsp+112], rsi 000a2 74 2f je SHORT $LN235@stbi__psd_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 000a4 8b 8f c8 00 00 00 mov ecx, DWORD PTR [rdi+200] 000aa 2b 8f c0 00 00 00 sub ecx, DWORD PTR [rdi+192] ; 1114 : if (blen < n) { 000b0 83 f9 06 cmp ecx, 6 000b3 7d 1e jge SHORT $LN235@stbi__psd_ ; 1115 : s->img_buffer = s->img_buffer_end; 000b5 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 000bc ba 06 00 00 00 mov edx, 6 000c1 2b d1 sub edx, ecx 000c3 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 000ca 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 000ce ff 57 18 call QWORD PTR [rdi+24] ; 1117 : return; 000d1 eb 08 jmp SHORT $LN75@stbi__psd_ $LN235@stbi__psd_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 000d3 48 83 87 c0 00 00 00 06 add QWORD PTR [rdi+192], 6 $LN75@stbi__psd_: ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); 000db 48 8b cf mov rcx, rdi 000de e8 00 00 00 00 call stbi__get16be 000e3 89 84 24 c0 00 00 00 mov DWORD PTR channelCount$1$[rsp], eax 000ea 8b f0 mov esi, eax ; 5690 : if (channelCount < 0 || channelCount > 16) 000ec 83 f8 10 cmp eax, 16 000ef 0f 87 b1 0b 00 00 ja $LN35@stbi__psd_ 000f5 4c 89 74 24 58 mov QWORD PTR [rsp+88], r14 ; 1168 : stbi__uint32 z = stbi__get16be(s); 000fa 48 8b cf mov rcx, rdi ; 5690 : if (channelCount < 0 || channelCount > 16) 000fd 4c 89 7c 24 50 mov QWORD PTR [rsp+80], r15 ; 1168 : stbi__uint32 z = stbi__get16be(s); 00102 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00107 48 8b cf mov rcx, rdi 0010a 44 8b f8 mov r15d, eax 0010d e8 00 00 00 00 call stbi__get16be 00112 41 c1 e7 10 shl r15d, 16 ; 1168 : stbi__uint32 z = stbi__get16be(s); 00116 48 8b cf mov rcx, rdi ; 1169 : return (z << 16) + stbi__get16be(s); 00119 44 03 f8 add r15d, eax 0011c 44 89 7c 24 38 mov DWORD PTR $T9[rsp], r15d ; 1168 : stbi__uint32 z = stbi__get16be(s); 00121 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00126 48 8b cf mov rcx, rdi 00129 44 8b f0 mov r14d, eax 0012c e8 00 00 00 00 call stbi__get16be 00131 41 c1 e6 10 shl r14d, 16 00135 44 03 f0 add r14d, eax 00138 44 89 74 24 34 mov DWORD PTR $T8[rsp], r14d ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0013d 41 81 ff 00 00 00 01 cmp r15d, 16777216 ; 01000000H 00144 0f 8f 32 0b 00 00 jg $LN240@stbi__psd_ ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0014a 41 81 fe 00 00 00 01 cmp r14d, 16777216 ; 01000000H 00151 0f 8f 25 0b 00 00 jg $LN240@stbi__psd_ ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); 00157 48 8b cf mov rcx, rdi 0015a e8 00 00 00 00 call stbi__get16be 0015f 89 44 24 30 mov DWORD PTR bitdepth$1$[rsp], eax ; 5702 : if (bitdepth != 8 && bitdepth != 16) 00163 8d 48 f8 lea ecx, DWORD PTR [rax-8] 00166 f7 c1 f7 ff ff ff test ecx, -9 ; fffffff7H 0016c 74 2a je SHORT $LN38@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 0016e 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00174 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0017d b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00182 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00186 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BG@NOLDLPP@unsupported?5bit?5depth@ 0018d 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); 00191 33 c0 xor eax, eax 00193 e9 66 03 00 00 jmp $LN330@stbi__psd_ $LN38@stbi__psd_: ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) 00198 48 8b cf mov rcx, rdi 0019b e8 00 00 00 00 call stbi__get16be 001a0 83 f8 03 cmp eax, 3 001a3 74 2a je SHORT $LN39@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 001a5 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001ab 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001b4 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 001b9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001bd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BD@IOGGBMNK@wrong?5color?5format@ 001c4 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); 001c8 33 c0 xor eax, eax 001ca e9 2f 03 00 00 jmp $LN330@stbi__psd_ $LN39@stbi__psd_: ; 1168 : stbi__uint32 z = stbi__get16be(s); 001cf 48 8b cf mov rcx, rdi 001d2 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 001d7 48 8b cf mov rcx, rdi 001da 8b d8 mov ebx, eax 001dc e8 00 00 00 00 call stbi__get16be 001e1 8b c8 mov ecx, eax 001e3 c1 e3 10 shl ebx, 16 001e6 03 cb add ecx, ebx ; 1107 : if (n == 0) return; // already there! 001e8 74 50 je SHORT $LN95@stbi__psd_ ; 1108 : if (n < 0) { 001ea 85 c9 test ecx, ecx 001ec 79 10 jns SHORT $LN97@stbi__psd_ ; 1109 : s->img_buffer = s->img_buffer_end; 001ee 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 001f5 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax ; 1110 : return; 001fc eb 3c jmp SHORT $LN95@stbi__psd_ $LN97@stbi__psd_: ; 1111 : } ; 1112 : if (s->io.read) { 001fe 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 00203 74 2b je SHORT $LN236@stbi__psd_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00205 8b 97 c8 00 00 00 mov edx, DWORD PTR [rdi+200] 0020b 2b 97 c0 00 00 00 sub edx, DWORD PTR [rdi+192] ; 1114 : if (blen < n) { 00211 3b d1 cmp edx, ecx 00213 7d 1b jge SHORT $LN236@stbi__psd_ ; 1115 : s->img_buffer = s->img_buffer_end; 00215 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0021c 2b ca sub ecx, edx 0021e 8b d1 mov edx, ecx 00220 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00227 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 0022b ff 57 18 call QWORD PTR [rdi+24] ; 1117 : return; 0022e eb 0a jmp SHORT $LN95@stbi__psd_ $LN236@stbi__psd_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00230 48 63 c1 movsxd rax, ecx 00233 48 01 87 c0 00 00 00 add QWORD PTR [rdi+192], rax $LN95@stbi__psd_: ; 1168 : stbi__uint32 z = stbi__get16be(s); 0023a 48 8b cf mov rcx, rdi 0023d e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 00242 48 8b cf mov rcx, rdi 00245 8b d8 mov ebx, eax 00247 e8 00 00 00 00 call stbi__get16be 0024c 8b c8 mov ecx, eax 0024e c1 e3 10 shl ebx, 16 00251 03 cb add ecx, ebx ; 1107 : if (n == 0) return; // already there! 00253 74 50 je SHORT $LN103@stbi__psd_ ; 1108 : if (n < 0) { 00255 85 c9 test ecx, ecx 00257 79 10 jns SHORT $LN105@stbi__psd_ ; 1109 : s->img_buffer = s->img_buffer_end; 00259 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 00260 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax ; 1110 : return; 00267 eb 3c jmp SHORT $LN103@stbi__psd_ $LN105@stbi__psd_: ; 1111 : } ; 1112 : if (s->io.read) { 00269 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 0026e 74 2b je SHORT $LN237@stbi__psd_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00270 8b 97 c8 00 00 00 mov edx, DWORD PTR [rdi+200] 00276 2b 97 c0 00 00 00 sub edx, DWORD PTR [rdi+192] ; 1114 : if (blen < n) { 0027c 3b d1 cmp edx, ecx 0027e 7d 1b jge SHORT $LN237@stbi__psd_ ; 1115 : s->img_buffer = s->img_buffer_end; 00280 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00287 2b ca sub ecx, edx 00289 8b d1 mov edx, ecx 0028b 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00292 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 00296 ff 57 18 call QWORD PTR [rdi+24] ; 1117 : return; 00299 eb 0a jmp SHORT $LN103@stbi__psd_ $LN237@stbi__psd_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0029b 48 63 c1 movsxd rax, ecx 0029e 48 01 87 c0 00 00 00 add QWORD PTR [rdi+192], rax $LN103@stbi__psd_: ; 1168 : stbi__uint32 z = stbi__get16be(s); 002a5 48 8b cf mov rcx, rdi 002a8 e8 00 00 00 00 call stbi__get16be ; 1169 : return (z << 16) + stbi__get16be(s); 002ad 48 8b cf mov rcx, rdi 002b0 8b d8 mov ebx, eax 002b2 e8 00 00 00 00 call stbi__get16be 002b7 8b c8 mov ecx, eax 002b9 c1 e3 10 shl ebx, 16 002bc 03 cb add ecx, ebx ; 1107 : if (n == 0) return; // already there! 002be 74 50 je SHORT $LN111@stbi__psd_ ; 1108 : if (n < 0) { 002c0 85 c9 test ecx, ecx 002c2 79 10 jns SHORT $LN113@stbi__psd_ ; 1109 : s->img_buffer = s->img_buffer_end; 002c4 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 002cb 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax ; 1110 : return; 002d2 eb 3c jmp SHORT $LN111@stbi__psd_ $LN113@stbi__psd_: ; 1111 : } ; 1112 : if (s->io.read) { 002d4 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 002d9 74 2b je SHORT $LN238@stbi__psd_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 002db 8b 97 c8 00 00 00 mov edx, DWORD PTR [rdi+200] 002e1 2b 97 c0 00 00 00 sub edx, DWORD PTR [rdi+192] ; 1114 : if (blen < n) { 002e7 3b d1 cmp edx, ecx 002e9 7d 1b jge SHORT $LN238@stbi__psd_ ; 1115 : s->img_buffer = s->img_buffer_end; 002eb 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 002f2 2b ca sub ecx, edx 002f4 8b d1 mov edx, ecx 002f6 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 002fd 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 00301 ff 57 18 call QWORD PTR [rdi+24] ; 1117 : return; 00304 eb 0a jmp SHORT $LN111@stbi__psd_ $LN238@stbi__psd_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00306 48 63 c1 movsxd rax, ecx 00309 48 01 87 c0 00 00 00 add QWORD PTR [rdi+192], rax $LN111@stbi__psd_: ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); 00310 48 8b cf mov rcx, rdi 00313 e8 00 00 00 00 call stbi__get16be 00318 8b d8 mov ebx, eax ; 5732 : if (compression > 1) 0031a 83 f8 01 cmp eax, 1 0031d 7e 2a jle SHORT $LN40@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 0031f 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00325 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0032e b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00333 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00337 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BA@MCNBDLPD@bad?5compression@ 0033e 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); 00342 33 c0 xor eax, eax 00344 e9 b5 01 00 00 jmp $LN330@stbi__psd_ $LN40@stbi__psd_: ; 467 : if (a < 0 || b < 0) return 0; 00349 45 85 f6 test r14d, r14d 0034c 0f 88 2a 09 00 00 js $LN240@stbi__psd_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00352 75 0a jne SHORT $LN128@stbi__psd_ 00354 42 8d 0c b5 00 00 00 00 lea ecx, DWORD PTR [r14*4] 0035c eb 22 jmp SHORT $LN243@stbi__psd_ $LN128@stbi__psd_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0035e b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00363 99 cdq 00364 41 f7 fe idiv r14d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00367 83 f8 04 cmp eax, 4 0036a 0f 8c 0c 09 00 00 jl $LN240@stbi__psd_ 00370 42 8d 0c b5 00 00 00 00 lea ecx, DWORD PTR [r14*4] ; 467 : if (a < 0 || b < 0) return 0; 00378 85 c9 test ecx, ecx 0037a 0f 88 fc 08 00 00 js $LN240@stbi__psd_ $LN243@stbi__psd_: 00380 45 85 ff test r15d, r15d 00383 0f 88 f3 08 00 00 js $LN240@stbi__psd_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00389 74 11 je SHORT $LN241@stbi__psd_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0038b b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00390 99 cdq 00391 41 f7 ff idiv r15d ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00394 3b c8 cmp ecx, eax 00396 0f 8f e0 08 00 00 jg $LN240@stbi__psd_ $LN241@stbi__psd_: 0039c 48 89 ac 24 90 00 00 00 mov QWORD PTR [rsp+144], rbp 003a4 41 8b ef mov ebp, r15d 003a7 41 0f af ee imul ebp, r14d 003ab 4c 89 64 24 68 mov QWORD PTR [rsp+104], r12 ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); 003b0 8d 04 ad 00 00 00 00 lea eax, DWORD PTR [rbp*4] 003b7 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 003ba ff 15 00 00 00 00 call QWORD PTR __imp_malloc 003c0 48 89 44 24 40 mov QWORD PTR out$1$[rsp], rax 003c5 4c 8b e0 mov r12, rax ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 003c8 48 85 c0 test rax, rax 003cb 75 2a jne SHORT $LN44@stbi__psd_ ; 431 : stbi__g_failure_reason = str; 003cd 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 003d3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 003dc b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 003e1 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 003e5 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 003ec 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 003f0 33 c0 xor eax, eax 003f2 e9 fa 00 00 00 jmp $LN332@stbi__psd_ $LN44@stbi__psd_: 003f7 4c 89 6c 24 60 mov QWORD PTR [rsp+96], r13 ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { 003fc 85 db test ebx, ebx 003fe 0f 84 10 01 00 00 je $LN45@stbi__psd_ ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); 00404 41 8b cf mov ecx, r15d 00407 0f af ce imul ecx, esi 0040a 03 c9 add ecx, ecx ; 1107 : if (n == 0) return; // already there! 0040c 74 50 je SHORT $LN150@stbi__psd_ ; 1108 : if (n < 0) { 0040e 85 c9 test ecx, ecx 00410 79 10 jns SHORT $LN152@stbi__psd_ ; 1109 : s->img_buffer = s->img_buffer_end; 00412 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 00419 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax ; 1110 : return; 00420 eb 3c jmp SHORT $LN150@stbi__psd_ $LN152@stbi__psd_: ; 1111 : } ; 1112 : if (s->io.read) { 00422 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 00427 74 2b je SHORT $LN239@stbi__psd_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00429 8b 97 c8 00 00 00 mov edx, DWORD PTR [rdi+200] 0042f 2b 97 c0 00 00 00 sub edx, DWORD PTR [rdi+192] ; 1114 : if (blen < n) { 00435 3b d1 cmp edx, ecx 00437 7d 1b jge SHORT $LN239@stbi__psd_ ; 1115 : s->img_buffer = s->img_buffer_end; 00439 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00440 2b ca sub ecx, edx 00442 8b d1 mov edx, ecx 00444 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0044b 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 0044f ff 57 18 call QWORD PTR [rdi+24] ; 1117 : return; 00452 eb 0a jmp SHORT $LN150@stbi__psd_ $LN239@stbi__psd_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00454 48 63 c1 movsxd rax, ecx 00457 48 01 87 c0 00 00 00 add QWORD PTR [rdi+192], rax $LN150@stbi__psd_: ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { 0045e 45 33 ed xor r13d, r13d 00461 b8 ff 00 00 00 mov eax, 255 ; 000000ffH 00466 41 8b dd mov ebx, r13d 00469 0f 1f 80 00 00 00 00 npad 7 $LL4@stbi__psd_: ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; 00470 48 63 d3 movsxd rdx, ebx 00473 49 03 d4 add rdx, r12 ; 5773 : if (channel >= channelCount) { 00476 3b de cmp ebx, esi 00478 7c 24 jl SHORT $LN47@stbi__psd_ ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) 0047a 85 ed test ebp, ebp 0047c 7e 34 jle SHORT $LN2@stbi__psd_ ; 5776 : *p = (channel == 3 ? 255 : 0); 0047e 83 fb 03 cmp ebx, 3 00481 41 8b cd mov ecx, r13d 00484 0f 44 c8 cmove ecx, eax 00487 8b c5 mov eax, ebp 00489 0f 1f 80 00 00 00 00 npad 7 $LL7@stbi__psd_: 00490 88 0a mov BYTE PTR [rdx], cl 00492 48 8d 52 04 lea rdx, QWORD PTR [rdx+4] 00496 48 83 e8 01 sub rax, 1 0049a 75 f4 jne SHORT $LL7@stbi__psd_ ; 5777 : } 0049c eb 0f jmp SHORT $LN334@stbi__psd_ $LN47@stbi__psd_: ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { 0049e 44 8b c5 mov r8d, ebp 004a1 48 8b cf mov rcx, rdi 004a4 e8 00 00 00 00 call stbi__psd_decode_rle 004a9 85 c0 test eax, eax 004ab 74 11 je SHORT $LN188@stbi__psd_ $LN334@stbi__psd_: ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { 004ad b8 ff 00 00 00 mov eax, 255 ; 000000ffH $LN2@stbi__psd_: 004b2 ff c3 inc ebx 004b4 83 fb 04 cmp ebx, 4 004b7 7c b7 jl SHORT $LL4@stbi__psd_ ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { 004b9 e9 82 01 00 00 jmp $LN9@stbi__psd_ $LN188@stbi__psd_: ; 5781 : STBI_FREE(out); 004be 49 8b cc mov rcx, r12 004c1 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 004c7 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 004cd 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 004d6 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 004db 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 004df 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07DPPMCAKL@corrupt@ 004e6 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN338@stbi__psd_: ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); 004ea 33 c0 xor eax, eax $LN333@stbi__psd_: 004ec 4c 8b 6c 24 60 mov r13, QWORD PTR [rsp+96] $LN332@stbi__psd_: 004f1 4c 8b 64 24 68 mov r12, QWORD PTR [rsp+104] 004f6 48 8b ac 24 90 00 00 00 mov rbp, QWORD PTR [rsp+144] $LN330@stbi__psd_: 004fe 4c 8b 74 24 58 mov r14, QWORD PTR [rsp+88] 00503 4c 8b 7c 24 50 mov r15, QWORD PTR [rsp+80] 00508 48 8b 74 24 70 mov rsi, QWORD PTR [rsp+112] ; 5873 : } 0050d 48 83 c4 78 add rsp, 120 ; 00000078H 00511 5f pop rdi 00512 5b pop rbx 00513 c3 ret 0 $LN45@stbi__psd_: ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { 00514 45 33 ed xor r13d, r13d 00517 4d 8b fc mov r15, r12 0051a 45 8b f5 mov r14d, r13d 0051d b9 ff 00 00 00 mov ecx, 255 ; 000000ffH $LL10@stbi__psd_: ; 5793 : if (channel >= channelCount) { 00522 44 3b f6 cmp r14d, esi 00525 7c 2a jl SHORT $LN50@stbi__psd_ ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; 00527 41 83 fe 03 cmp r14d, 3 0052b 41 8b d5 mov edx, r13d 0052e 49 8b c7 mov rax, r15 00531 0f 44 d1 cmove edx, ecx ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) 00534 85 ed test ebp, ebp 00536 0f 8e e1 00 00 00 jle $LN8@stbi__psd_ ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; 0053c 8b cd mov ecx, ebp 0053e 66 90 npad 2 $LL16@stbi__psd_: ; 5805 : *p = val; 00540 88 10 mov BYTE PTR [rax], dl 00542 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00546 48 83 e9 01 sub rcx, 1 0054a 75 f4 jne SHORT $LL16@stbi__psd_ ; 5806 : } ; 5807 : } 0054c e9 c7 00 00 00 jmp $LN335@stbi__psd_ $LN50@stbi__psd_: ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc 00551 48 8b 84 24 b8 00 00 00 mov rax, QWORD PTR ri$[rsp] 00559 83 38 10 cmp DWORD PTR [rax], 16 0055c 75 2c jne SHORT $LN54@stbi__psd_ ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; 0055e 49 8b dc mov rbx, r12 ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) 00561 85 ed test ebp, ebp 00563 0f 8e b4 00 00 00 jle $LN8@stbi__psd_ ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; 00569 8b f5 mov esi, ebp 0056b 0f 1f 44 00 00 npad 5 $LL19@stbi__psd_: ; 5812 : *q = (stbi__uint16)stbi__get16be(s); 00570 48 8b cf mov rcx, rdi 00573 e8 00 00 00 00 call stbi__get16be 00578 66 89 03 mov WORD PTR [rbx], ax 0057b 48 8d 5b 08 lea rbx, QWORD PTR [rbx+8] 0057f 48 83 ee 01 sub rsi, 1 00583 75 eb jne SHORT $LL19@stbi__psd_ ; 5813 : } 00585 e9 87 00 00 00 jmp $LN336@stbi__psd_ $LN54@stbi__psd_: ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc 0058a 83 7c 24 30 10 cmp DWORD PTR bitdepth$1$[rsp], 16 0058f 49 8b df mov rbx, r15 00592 75 25 jne SHORT $LN56@stbi__psd_ ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) 00594 85 ed test ebp, ebp 00596 0f 8e 81 00 00 00 jle $LN8@stbi__psd_ 0059c 8b f5 mov esi, ebp 0059e 66 90 npad 2 $LL22@stbi__psd_: ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); 005a0 48 8b cf mov rcx, rdi 005a3 e8 00 00 00 00 call stbi__get16be 005a8 c1 f8 08 sar eax, 8 005ab 88 03 mov BYTE PTR [rbx], al 005ad 48 8d 5b 04 lea rbx, QWORD PTR [rbx+4] 005b1 48 83 ee 01 sub rsi, 1 005b5 75 e9 jne SHORT $LL22@stbi__psd_ ; 5819 : } 005b7 eb 58 jmp SHORT $LN336@stbi__psd_ $LN56@stbi__psd_: ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) 005b9 85 ed test ebp, ebp 005bb 7e 60 jle SHORT $LN8@stbi__psd_ 005bd 8b f5 mov esi, ebp 005bf 90 npad 1 $LL25@stbi__psd_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 005c0 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 005c7 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 005ce 73 0f jae SHORT $LN143@stbi__psd_ ; 1078 : return *s->img_buffer++; 005d0 0f b6 08 movzx ecx, BYTE PTR [rax] 005d3 48 ff c0 inc rax 005d6 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 005dd eb 26 jmp SHORT $LN142@stbi__psd_ $LN143@stbi__psd_: ; 1079 : if (s->read_from_callbacks) { 005df 44 39 6f 30 cmp DWORD PTR [rdi+48], r13d 005e3 74 1e je SHORT $LN144@stbi__psd_ ; 1080 : stbi__refill_buffer(s); 005e5 48 8b cf mov rcx, rdi 005e8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 005ed 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 005f4 0f b6 08 movzx ecx, BYTE PTR [rax] 005f7 48 ff c0 inc rax 005fa 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00601 eb 02 jmp SHORT $LN142@stbi__psd_ $LN144@stbi__psd_: ; 1082 : } ; 1083 : return 0; 00603 32 c9 xor cl, cl $LN142@stbi__psd_: ; 5822 : *p = stbi__get8(s); 00605 88 0b mov BYTE PTR [rbx], cl 00607 48 83 c3 04 add rbx, 4 0060b 48 83 ee 01 sub rsi, 1 0060f 75 af jne SHORT $LL25@stbi__psd_ $LN336@stbi__psd_: ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { 00611 8b b4 24 c0 00 00 00 mov esi, DWORD PTR channelCount$1$[rsp] $LN335@stbi__psd_: 00618 b9 ff 00 00 00 mov ecx, 255 ; 000000ffH $LN8@stbi__psd_: 0061d 41 ff c6 inc r14d 00620 49 83 c4 02 add r12, 2 00624 49 ff c7 inc r15 00627 41 83 fe 04 cmp r14d, 4 0062b 0f 8c f1 fe ff ff jl $LL10@stbi__psd_ 00631 4c 8b 64 24 40 mov r12, QWORD PTR out$1$[rsp] 00636 44 8b 74 24 34 mov r14d, DWORD PTR $T8[rsp] 0063b 44 8b 7c 24 38 mov r15d, DWORD PTR $T9[rsp] $LN9@stbi__psd_: ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { 00640 4c 8b 94 24 b8 00 00 00 mov r10, QWORD PTR ri$[rsp] 00648 83 fe 04 cmp esi, 4 0064b 0f 8c bb 05 00 00 jl $LN216@stbi__psd_ ; 5831 : if (ri->bits_per_channel == 16) { 00651 41 83 3a 10 cmp DWORD PTR [r10], 16 00655 48 63 d5 movsxd rdx, ebp 00658 0f 85 ec 02 00 00 jne $LN59@stbi__psd_ ; 5832 : for (i = 0; i < w * h; ++i) { 0065e f3 0f 10 1d 00 00 00 00 movss xmm3, DWORD PTR __real@477fff00 00666 41 bb fd ff 00 00 mov r11d, 65533 ; 0000fffdH 0066c f3 0f 10 25 00 00 00 00 movss xmm4, DWORD PTR __real@3f800000 00674 48 83 fa 04 cmp rdx, 4 00678 0f 8c 26 02 00 00 jl $LC210@stbi__psd_ 0067e 4c 8d 42 fc lea r8, QWORD PTR [rdx-4] 00682 49 c1 e8 02 shr r8, 2 00686 49 8d 4c 24 0a lea rcx, QWORD PTR [r12+10] 0068b 49 ff c0 inc r8 0068e 4e 8d 2c 85 00 00 00 00 lea r13, QWORD PTR [r8*4] 00696 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL215@stbi__psd_: ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { 006a0 44 0f b7 49 fc movzx r9d, WORD PTR [rcx-4] 006a5 41 8d 41 ff lea eax, DWORD PTR [r9-1] 006a9 66 41 3b c3 cmp ax, r11w 006ad 77 6f ja SHORT $LN211@stbi__psd_ ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); 006af 0f b7 41 f6 movzx eax, WORD PTR [rcx-10] 006b3 0f 57 c0 xorps xmm0, xmm0 006b6 f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 006bb 0f 28 d4 movaps xmm2, xmm4 006be 0f 28 cc movaps xmm1, xmm4 006c1 f3 0f 5e c3 divss xmm0, xmm3 006c5 f3 0f 5e d0 divss xmm2, xmm0 006c9 0f 57 c0 xorps xmm0, xmm0 006cc f3 0f 2a c0 cvtsi2ss xmm0, eax 006d0 f3 0f 5c ca subss xmm1, xmm2 006d4 f3 0f 59 c2 mulss xmm0, xmm2 006d8 f3 0f 59 cb mulss xmm1, xmm3 006dc f3 0f 58 c1 addss xmm0, xmm1 006e0 f3 0f 2c c0 cvttss2si eax, xmm0 006e4 0f 57 c0 xorps xmm0, xmm0 006e7 66 89 41 f6 mov WORD PTR [rcx-10], ax ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); 006eb 0f b7 41 f8 movzx eax, WORD PTR [rcx-8] 006ef f3 0f 2a c0 cvtsi2ss xmm0, eax 006f3 f3 0f 59 c2 mulss xmm0, xmm2 006f7 f3 0f 58 c1 addss xmm0, xmm1 006fb f3 0f 2c c0 cvttss2si eax, xmm0 006ff 0f 57 c0 xorps xmm0, xmm0 00702 66 89 41 f8 mov WORD PTR [rcx-8], ax ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); 00706 0f b7 41 fa movzx eax, WORD PTR [rcx-6] 0070a f3 0f 2a c0 cvtsi2ss xmm0, eax 0070e f3 0f 59 c2 mulss xmm0, xmm2 00712 f3 0f 58 c1 addss xmm0, xmm1 00716 f3 0f 2c c0 cvttss2si eax, xmm0 0071a 66 89 41 fa mov WORD PTR [rcx-6], ax $LN211@stbi__psd_: ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { 0071e 44 0f b7 49 04 movzx r9d, WORD PTR [rcx+4] 00723 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00727 66 41 3b c3 cmp ax, r11w 0072b 77 6d ja SHORT $LN212@stbi__psd_ ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); 0072d 0f b7 41 fe movzx eax, WORD PTR [rcx-2] 00731 0f 57 c0 xorps xmm0, xmm0 00734 f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00739 0f 28 d4 movaps xmm2, xmm4 0073c 0f 28 cc movaps xmm1, xmm4 0073f f3 0f 5e c3 divss xmm0, xmm3 00743 f3 0f 5e d0 divss xmm2, xmm0 00747 0f 57 c0 xorps xmm0, xmm0 0074a f3 0f 2a c0 cvtsi2ss xmm0, eax 0074e f3 0f 5c ca subss xmm1, xmm2 00752 f3 0f 59 c2 mulss xmm0, xmm2 00756 f3 0f 59 cb mulss xmm1, xmm3 0075a f3 0f 58 c1 addss xmm0, xmm1 0075e f3 0f 2c c0 cvttss2si eax, xmm0 00762 0f 57 c0 xorps xmm0, xmm0 00765 66 89 41 fe mov WORD PTR [rcx-2], ax ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); 00769 0f b7 01 movzx eax, WORD PTR [rcx] 0076c f3 0f 2a c0 cvtsi2ss xmm0, eax 00770 f3 0f 59 c2 mulss xmm0, xmm2 00774 f3 0f 58 c1 addss xmm0, xmm1 00778 f3 0f 2c c0 cvttss2si eax, xmm0 0077c 0f 57 c0 xorps xmm0, xmm0 0077f 66 89 01 mov WORD PTR [rcx], ax ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); 00782 0f b7 41 02 movzx eax, WORD PTR [rcx+2] 00786 f3 0f 2a c0 cvtsi2ss xmm0, eax 0078a f3 0f 59 c2 mulss xmm0, xmm2 0078e f3 0f 58 c1 addss xmm0, xmm1 00792 f3 0f 2c c0 cvttss2si eax, xmm0 00796 66 89 41 02 mov WORD PTR [rcx+2], ax $LN212@stbi__psd_: ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { 0079a 44 0f b7 49 0c movzx r9d, WORD PTR [rcx+12] 0079f 41 8d 41 ff lea eax, DWORD PTR [r9-1] 007a3 66 41 3b c3 cmp ax, r11w 007a7 77 6f ja SHORT $LN213@stbi__psd_ ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); 007a9 0f b7 41 06 movzx eax, WORD PTR [rcx+6] 007ad 0f 57 c0 xorps xmm0, xmm0 007b0 f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 007b5 0f 28 d4 movaps xmm2, xmm4 007b8 0f 28 cc movaps xmm1, xmm4 007bb f3 0f 5e c3 divss xmm0, xmm3 007bf f3 0f 5e d0 divss xmm2, xmm0 007c3 0f 57 c0 xorps xmm0, xmm0 007c6 f3 0f 2a c0 cvtsi2ss xmm0, eax 007ca f3 0f 5c ca subss xmm1, xmm2 007ce f3 0f 59 c2 mulss xmm0, xmm2 007d2 f3 0f 59 cb mulss xmm1, xmm3 007d6 f3 0f 58 c1 addss xmm0, xmm1 007da f3 0f 2c c0 cvttss2si eax, xmm0 007de 0f 57 c0 xorps xmm0, xmm0 007e1 66 89 41 06 mov WORD PTR [rcx+6], ax ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); 007e5 0f b7 41 08 movzx eax, WORD PTR [rcx+8] 007e9 f3 0f 2a c0 cvtsi2ss xmm0, eax 007ed f3 0f 59 c2 mulss xmm0, xmm2 007f1 f3 0f 58 c1 addss xmm0, xmm1 007f5 f3 0f 2c c0 cvttss2si eax, xmm0 007f9 0f 57 c0 xorps xmm0, xmm0 007fc 66 89 41 08 mov WORD PTR [rcx+8], ax ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); 00800 0f b7 41 0a movzx eax, WORD PTR [rcx+10] 00804 f3 0f 2a c0 cvtsi2ss xmm0, eax 00808 f3 0f 59 c2 mulss xmm0, xmm2 0080c f3 0f 58 c1 addss xmm0, xmm1 00810 f3 0f 2c c0 cvttss2si eax, xmm0 00814 66 89 41 0a mov WORD PTR [rcx+10], ax $LN213@stbi__psd_: ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { 00818 44 0f b7 49 14 movzx r9d, WORD PTR [rcx+20] 0081d 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00821 66 41 3b c3 cmp ax, r11w 00825 77 6f ja SHORT $LN214@stbi__psd_ ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); 00827 0f b7 41 0e movzx eax, WORD PTR [rcx+14] 0082b 0f 57 c0 xorps xmm0, xmm0 0082e f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00833 0f 28 d4 movaps xmm2, xmm4 00836 0f 28 cc movaps xmm1, xmm4 00839 f3 0f 5e c3 divss xmm0, xmm3 0083d f3 0f 5e d0 divss xmm2, xmm0 00841 0f 57 c0 xorps xmm0, xmm0 00844 f3 0f 2a c0 cvtsi2ss xmm0, eax 00848 f3 0f 5c ca subss xmm1, xmm2 0084c f3 0f 59 c2 mulss xmm0, xmm2 00850 f3 0f 59 cb mulss xmm1, xmm3 00854 f3 0f 58 c1 addss xmm0, xmm1 00858 f3 0f 2c c0 cvttss2si eax, xmm0 0085c 0f 57 c0 xorps xmm0, xmm0 0085f 66 89 41 0e mov WORD PTR [rcx+14], ax ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); 00863 0f b7 41 10 movzx eax, WORD PTR [rcx+16] 00867 f3 0f 2a c0 cvtsi2ss xmm0, eax 0086b f3 0f 59 c2 mulss xmm0, xmm2 0086f f3 0f 58 c1 addss xmm0, xmm1 00873 f3 0f 2c c0 cvttss2si eax, xmm0 00877 0f 57 c0 xorps xmm0, xmm0 0087a 66 89 41 10 mov WORD PTR [rcx+16], ax ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); 0087e 0f b7 41 12 movzx eax, WORD PTR [rcx+18] 00882 f3 0f 2a c0 cvtsi2ss xmm0, eax 00886 f3 0f 59 c2 mulss xmm0, xmm2 0088a f3 0f 58 c1 addss xmm0, xmm1 0088e f3 0f 2c c0 cvttss2si eax, xmm0 00892 66 89 41 12 mov WORD PTR [rcx+18], ax $LN214@stbi__psd_: 00896 48 83 c1 20 add rcx, 32 ; 00000020H 0089a 49 83 e8 01 sub r8, 1 0089e 0f 85 fc fd ff ff jne $LL215@stbi__psd_ $LC210@stbi__psd_: ; 5832 : for (i = 0; i < w * h; ++i) { 008a4 4c 3b ea cmp r13, rdx 008a7 0f 8d 5f 03 00 00 jge $LN216@stbi__psd_ 008ad 4a 8d 0c ed 02 00 00 00 lea rcx, QWORD PTR [r13*8+2] 008b5 49 03 cc add rcx, r12 008b8 49 2b d5 sub rdx, r13 $LC28@stbi__psd_: ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { 008bb 44 0f b7 41 04 movzx r8d, WORD PTR [rcx+4] 008c0 41 8d 40 ff lea eax, DWORD PTR [r8-1] 008c4 66 41 3b c3 cmp ax, r11w 008c8 77 6d ja SHORT $LN26@stbi__psd_ ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); 008ca 0f b7 41 fe movzx eax, WORD PTR [rcx-2] 008ce 0f 57 c0 xorps xmm0, xmm0 008d1 f3 41 0f 2a c0 cvtsi2ss xmm0, r8d 008d6 0f 28 d4 movaps xmm2, xmm4 008d9 0f 28 cc movaps xmm1, xmm4 008dc f3 0f 5e c3 divss xmm0, xmm3 008e0 f3 0f 5e d0 divss xmm2, xmm0 008e4 0f 57 c0 xorps xmm0, xmm0 008e7 f3 0f 2a c0 cvtsi2ss xmm0, eax 008eb f3 0f 5c ca subss xmm1, xmm2 008ef f3 0f 59 c2 mulss xmm0, xmm2 008f3 f3 0f 59 cb mulss xmm1, xmm3 008f7 f3 0f 58 c1 addss xmm0, xmm1 008fb f3 0f 2c c0 cvttss2si eax, xmm0 008ff 0f 57 c0 xorps xmm0, xmm0 00902 66 89 41 fe mov WORD PTR [rcx-2], ax ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); 00906 0f b7 01 movzx eax, WORD PTR [rcx] 00909 f3 0f 2a c0 cvtsi2ss xmm0, eax 0090d f3 0f 59 c2 mulss xmm0, xmm2 00911 f3 0f 58 c1 addss xmm0, xmm1 00915 f3 0f 2c c0 cvttss2si eax, xmm0 00919 0f 57 c0 xorps xmm0, xmm0 0091c 66 89 01 mov WORD PTR [rcx], ax ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); 0091f 0f b7 41 02 movzx eax, WORD PTR [rcx+2] 00923 f3 0f 2a c0 cvtsi2ss xmm0, eax 00927 f3 0f 59 c2 mulss xmm0, xmm2 0092b f3 0f 58 c1 addss xmm0, xmm1 0092f f3 0f 2c c0 cvttss2si eax, xmm0 00933 66 89 41 02 mov WORD PTR [rcx+2], ax $LN26@stbi__psd_: ; 5832 : for (i = 0; i < w * h; ++i) { 00937 48 83 c1 08 add rcx, 8 0093b 48 83 ea 01 sub rdx, 1 0093f 0f 85 76 ff ff ff jne $LC28@stbi__psd_ ; 5841 : } ; 5842 : } ; 5843 : } 00945 e9 c2 02 00 00 jmp $LN216@stbi__psd_ $LN59@stbi__psd_: ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { 0094a f3 0f 10 1d 00 00 00 00 movss xmm3, DWORD PTR __real@3f800000 00952 f3 0f 10 25 00 00 00 00 movss xmm4, DWORD PTR __real@437f0000 0095a 48 83 fa 04 cmp rdx, 4 0095e 0f 8c 0c 02 00 00 jl $LC217@stbi__psd_ 00964 4c 8d 42 fc lea r8, QWORD PTR [rdx-4] 00968 49 c1 e8 02 shr r8, 2 0096c 49 8d 4c 24 05 lea rcx, QWORD PTR [r12+5] 00971 49 ff c0 inc r8 00974 4e 8d 2c 85 00 00 00 00 lea r13, QWORD PTR [r8*4] 0097c 0f 1f 40 00 npad 4 $LL222@stbi__psd_: ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { 00980 44 0f b6 49 fe movzx r9d, BYTE PTR [rcx-2] 00985 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00989 3c fd cmp al, 253 ; 000000fdH 0098b 77 6c ja SHORT $LN218@stbi__psd_ ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); 0098d 0f b6 41 fb movzx eax, BYTE PTR [rcx-5] 00991 0f 57 c0 xorps xmm0, xmm0 00994 f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00999 0f 28 d3 movaps xmm2, xmm3 0099c 0f 28 cb movaps xmm1, xmm3 0099f f3 0f 5e c4 divss xmm0, xmm4 009a3 f3 0f 5e d0 divss xmm2, xmm0 009a7 0f 57 c0 xorps xmm0, xmm0 009aa f3 0f 2a c0 cvtsi2ss xmm0, eax 009ae f3 0f 5c ca subss xmm1, xmm2 009b2 f3 0f 59 c2 mulss xmm0, xmm2 009b6 f3 0f 59 cc mulss xmm1, xmm4 009ba f3 0f 58 c1 addss xmm0, xmm1 009be f3 0f 2c c0 cvttss2si eax, xmm0 009c2 0f 57 c0 xorps xmm0, xmm0 009c5 88 41 fb mov BYTE PTR [rcx-5], al ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); 009c8 0f b6 41 fc movzx eax, BYTE PTR [rcx-4] 009cc f3 0f 2a c0 cvtsi2ss xmm0, eax 009d0 f3 0f 59 c2 mulss xmm0, xmm2 009d4 f3 0f 58 c1 addss xmm0, xmm1 009d8 f3 0f 2c c0 cvttss2si eax, xmm0 009dc 0f 57 c0 xorps xmm0, xmm0 009df 88 41 fc mov BYTE PTR [rcx-4], al ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); 009e2 0f b6 41 fd movzx eax, BYTE PTR [rcx-3] 009e6 f3 0f 2a c0 cvtsi2ss xmm0, eax 009ea f3 0f 59 c2 mulss xmm0, xmm2 009ee f3 0f 58 c1 addss xmm0, xmm1 009f2 f3 0f 2c c0 cvttss2si eax, xmm0 009f6 88 41 fd mov BYTE PTR [rcx-3], al $LN218@stbi__psd_: ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { 009f9 44 0f b6 49 02 movzx r9d, BYTE PTR [rcx+2] 009fe 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00a02 3c fd cmp al, 253 ; 000000fdH 00a04 77 6a ja SHORT $LN219@stbi__psd_ ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); 00a06 0f b6 41 ff movzx eax, BYTE PTR [rcx-1] 00a0a 0f 57 c0 xorps xmm0, xmm0 00a0d f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00a12 0f 28 d3 movaps xmm2, xmm3 00a15 0f 28 cb movaps xmm1, xmm3 00a18 f3 0f 5e c4 divss xmm0, xmm4 00a1c f3 0f 5e d0 divss xmm2, xmm0 00a20 0f 57 c0 xorps xmm0, xmm0 00a23 f3 0f 2a c0 cvtsi2ss xmm0, eax 00a27 f3 0f 5c ca subss xmm1, xmm2 00a2b f3 0f 59 c2 mulss xmm0, xmm2 00a2f f3 0f 59 cc mulss xmm1, xmm4 00a33 f3 0f 58 c1 addss xmm0, xmm1 00a37 f3 0f 2c c0 cvttss2si eax, xmm0 00a3b 0f 57 c0 xorps xmm0, xmm0 00a3e 88 41 ff mov BYTE PTR [rcx-1], al ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); 00a41 0f b6 01 movzx eax, BYTE PTR [rcx] 00a44 f3 0f 2a c0 cvtsi2ss xmm0, eax 00a48 f3 0f 59 c2 mulss xmm0, xmm2 00a4c f3 0f 58 c1 addss xmm0, xmm1 00a50 f3 0f 2c c0 cvttss2si eax, xmm0 00a54 0f 57 c0 xorps xmm0, xmm0 00a57 88 01 mov BYTE PTR [rcx], al ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); 00a59 0f b6 41 01 movzx eax, BYTE PTR [rcx+1] 00a5d f3 0f 2a c0 cvtsi2ss xmm0, eax 00a61 f3 0f 59 c2 mulss xmm0, xmm2 00a65 f3 0f 58 c1 addss xmm0, xmm1 00a69 f3 0f 2c c0 cvttss2si eax, xmm0 00a6d 88 41 01 mov BYTE PTR [rcx+1], al $LN219@stbi__psd_: ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { 00a70 44 0f b6 49 06 movzx r9d, BYTE PTR [rcx+6] 00a75 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00a79 3c fd cmp al, 253 ; 000000fdH 00a7b 77 6c ja SHORT $LN220@stbi__psd_ ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); 00a7d 0f b6 41 03 movzx eax, BYTE PTR [rcx+3] 00a81 0f 57 c0 xorps xmm0, xmm0 00a84 f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00a89 0f 28 d3 movaps xmm2, xmm3 00a8c 0f 28 cb movaps xmm1, xmm3 00a8f f3 0f 5e c4 divss xmm0, xmm4 00a93 f3 0f 5e d0 divss xmm2, xmm0 00a97 0f 57 c0 xorps xmm0, xmm0 00a9a f3 0f 2a c0 cvtsi2ss xmm0, eax 00a9e f3 0f 5c ca subss xmm1, xmm2 00aa2 f3 0f 59 c2 mulss xmm0, xmm2 00aa6 f3 0f 59 cc mulss xmm1, xmm4 00aaa f3 0f 58 c1 addss xmm0, xmm1 00aae f3 0f 2c c0 cvttss2si eax, xmm0 00ab2 0f 57 c0 xorps xmm0, xmm0 00ab5 88 41 03 mov BYTE PTR [rcx+3], al ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); 00ab8 0f b6 41 04 movzx eax, BYTE PTR [rcx+4] 00abc f3 0f 2a c0 cvtsi2ss xmm0, eax 00ac0 f3 0f 59 c2 mulss xmm0, xmm2 00ac4 f3 0f 58 c1 addss xmm0, xmm1 00ac8 f3 0f 2c c0 cvttss2si eax, xmm0 00acc 0f 57 c0 xorps xmm0, xmm0 00acf 88 41 04 mov BYTE PTR [rcx+4], al ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); 00ad2 0f b6 41 05 movzx eax, BYTE PTR [rcx+5] 00ad6 f3 0f 2a c0 cvtsi2ss xmm0, eax 00ada f3 0f 59 c2 mulss xmm0, xmm2 00ade f3 0f 58 c1 addss xmm0, xmm1 00ae2 f3 0f 2c c0 cvttss2si eax, xmm0 00ae6 88 41 05 mov BYTE PTR [rcx+5], al $LN220@stbi__psd_: ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { 00ae9 44 0f b6 49 0a movzx r9d, BYTE PTR [rcx+10] 00aee 41 8d 41 ff lea eax, DWORD PTR [r9-1] 00af2 3c fd cmp al, 253 ; 000000fdH 00af4 77 6c ja SHORT $LN221@stbi__psd_ ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); 00af6 0f b6 41 07 movzx eax, BYTE PTR [rcx+7] 00afa 0f 57 c0 xorps xmm0, xmm0 00afd f3 41 0f 2a c1 cvtsi2ss xmm0, r9d 00b02 0f 28 d3 movaps xmm2, xmm3 00b05 0f 28 cb movaps xmm1, xmm3 00b08 f3 0f 5e c4 divss xmm0, xmm4 00b0c f3 0f 5e d0 divss xmm2, xmm0 00b10 0f 57 c0 xorps xmm0, xmm0 00b13 f3 0f 2a c0 cvtsi2ss xmm0, eax 00b17 f3 0f 5c ca subss xmm1, xmm2 00b1b f3 0f 59 c2 mulss xmm0, xmm2 00b1f f3 0f 59 cc mulss xmm1, xmm4 00b23 f3 0f 58 c1 addss xmm0, xmm1 00b27 f3 0f 2c c0 cvttss2si eax, xmm0 00b2b 0f 57 c0 xorps xmm0, xmm0 00b2e 88 41 07 mov BYTE PTR [rcx+7], al ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); 00b31 0f b6 41 08 movzx eax, BYTE PTR [rcx+8] 00b35 f3 0f 2a c0 cvtsi2ss xmm0, eax 00b39 f3 0f 59 c2 mulss xmm0, xmm2 00b3d f3 0f 58 c1 addss xmm0, xmm1 00b41 f3 0f 2c c0 cvttss2si eax, xmm0 00b45 0f 57 c0 xorps xmm0, xmm0 00b48 88 41 08 mov BYTE PTR [rcx+8], al ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); 00b4b 0f b6 41 09 movzx eax, BYTE PTR [rcx+9] 00b4f f3 0f 2a c0 cvtsi2ss xmm0, eax 00b53 f3 0f 59 c2 mulss xmm0, xmm2 00b57 f3 0f 58 c1 addss xmm0, xmm1 00b5b f3 0f 2c c0 cvttss2si eax, xmm0 00b5f 88 41 09 mov BYTE PTR [rcx+9], al $LN221@stbi__psd_: 00b62 48 83 c1 10 add rcx, 16 00b66 49 83 e8 01 sub r8, 1 00b6a 0f 85 10 fe ff ff jne $LL222@stbi__psd_ $LC217@stbi__psd_: ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { 00b70 4c 3b ea cmp r13, rdx 00b73 0f 8d 93 00 00 00 jge $LN216@stbi__psd_ 00b79 4a 8d 0c ad 01 00 00 00 lea rcx, QWORD PTR [r13*4+1] 00b81 49 03 cc add rcx, r12 00b84 49 2b d5 sub rdx, r13 $LC31@stbi__psd_: ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { 00b87 44 0f b6 41 02 movzx r8d, BYTE PTR [rcx+2] 00b8c 41 8d 40 ff lea eax, DWORD PTR [r8-1] 00b90 3c fd cmp al, 253 ; 000000fdH 00b92 77 6a ja SHORT $LN29@stbi__psd_ ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); 00b94 0f b6 41 ff movzx eax, BYTE PTR [rcx-1] 00b98 0f 57 c0 xorps xmm0, xmm0 00b9b f3 41 0f 2a c0 cvtsi2ss xmm0, r8d 00ba0 0f 28 d3 movaps xmm2, xmm3 00ba3 0f 28 cb movaps xmm1, xmm3 00ba6 f3 0f 5e c4 divss xmm0, xmm4 00baa f3 0f 5e d0 divss xmm2, xmm0 00bae 0f 57 c0 xorps xmm0, xmm0 00bb1 f3 0f 2a c0 cvtsi2ss xmm0, eax 00bb5 f3 0f 5c ca subss xmm1, xmm2 00bb9 f3 0f 59 c2 mulss xmm0, xmm2 00bbd f3 0f 59 cc mulss xmm1, xmm4 00bc1 f3 0f 58 c1 addss xmm0, xmm1 00bc5 f3 0f 2c c0 cvttss2si eax, xmm0 00bc9 0f 57 c0 xorps xmm0, xmm0 00bcc 88 41 ff mov BYTE PTR [rcx-1], al ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); 00bcf 0f b6 01 movzx eax, BYTE PTR [rcx] 00bd2 f3 0f 2a c0 cvtsi2ss xmm0, eax 00bd6 f3 0f 59 c2 mulss xmm0, xmm2 00bda f3 0f 58 c1 addss xmm0, xmm1 00bde f3 0f 2c c0 cvttss2si eax, xmm0 00be2 0f 57 c0 xorps xmm0, xmm0 00be5 88 01 mov BYTE PTR [rcx], al ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); 00be7 0f b6 41 01 movzx eax, BYTE PTR [rcx+1] 00beb f3 0f 2a c0 cvtsi2ss xmm0, eax 00bef f3 0f 59 c2 mulss xmm0, xmm2 00bf3 f3 0f 58 c1 addss xmm0, xmm1 00bf7 f3 0f 2c c0 cvttss2si eax, xmm0 00bfb 88 41 01 mov BYTE PTR [rcx+1], al $LN29@stbi__psd_: ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { 00bfe 48 83 c1 04 add rcx, 4 00c02 48 83 ea 01 sub rdx, 1 00c06 0f 85 7b ff ff ff jne $LC31@stbi__psd_ $LN216@stbi__psd_: ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { 00c0c 44 8b 84 24 b0 00 00 00 mov r8d, DWORD PTR req_comp$[rsp] 00c14 41 f7 c0 fb ff ff ff test r8d, -5 ; fffffffbH 00c1b 74 2e je SHORT $LN66@stbi__psd_ ; 5861 : if (ri->bits_per_channel == 16) 00c1d 41 83 3a 10 cmp DWORD PTR [r10], 16 00c21 45 8b ce mov r9d, r14d 00c24 44 89 7c 24 20 mov DWORD PTR [rsp+32], r15d 00c29 ba 04 00 00 00 mov edx, 4 00c2e 49 8b cc mov rcx, r12 00c31 75 07 jne SHORT $LN64@stbi__psd_ ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); 00c33 e8 00 00 00 00 call stbi__convert_format16 00c38 eb 05 jmp SHORT $LN337@stbi__psd_ $LN64@stbi__psd_: ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); 00c3a e8 00 00 00 00 call stbi__convert_format $LN337@stbi__psd_: ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure 00c3f 4c 8b e0 mov r12, rax 00c42 48 85 c0 test rax, rax 00c45 0f 84 9f f8 ff ff je $LN338@stbi__psd_ $LN66@stbi__psd_: ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; 00c4b 48 8b 84 24 a8 00 00 00 mov rax, QWORD PTR comp$[rsp] 00c53 48 85 c0 test rax, rax 00c56 74 06 je SHORT $LN67@stbi__psd_ 00c58 c7 00 04 00 00 00 mov DWORD PTR [rax], 4 $LN67@stbi__psd_: ; 5869 : *y = h; 00c5e 48 8b 84 24 a0 00 00 00 mov rax, QWORD PTR y$[rsp] 00c66 44 89 38 mov DWORD PTR [rax], r15d ; 5870 : *x = w; 00c69 48 8b 84 24 98 00 00 00 mov rax, QWORD PTR x$[rsp] 00c71 44 89 30 mov DWORD PTR [rax], r14d ; 5871 : ; 5872 : return out; 00c74 49 8b c4 mov rax, r12 00c77 e9 70 f8 ff ff jmp $LN333@stbi__psd_ $LN240@stbi__psd_: ; 431 : stbi__g_failure_reason = str; 00c7c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00c82 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00c8b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00c90 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00c94 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 00c9b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); 00c9f 33 c0 xor eax, eax 00ca1 e9 58 f8 ff ff jmp $LN330@stbi__psd_ $LN35@stbi__psd_: ; 431 : stbi__g_failure_reason = str; 00ca6 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00cac 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00cb5 48 8b 74 24 70 mov rsi, QWORD PTR [rsp+112] 00cba b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00cbf 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00cc3 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BE@PJBNGDBE@wrong?5channel?5count@ 00cca 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); 00cce 33 c0 xor eax, eax ; 5873 : } 00cd0 48 83 c4 78 add rsp, 120 ; 00000078H 00cd4 5f pop rdi 00cd5 5b pop rbx 00cd6 c3 ret 0 stbi__psd_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pic_is4 _TEXT SEGMENT s$ = 48 str$ = 56 stbi__pic_is4 PROC ; COMDAT ; 5885 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H 0000f 48 8b f2 mov rsi, rdx 00012 48 8b d9 mov rbx, rcx 00015 33 ff xor edi, edi 00017 66 0f 1f 84 00 00 00 00 00 npad 9 $LL4@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00020 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00027 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0002e 73 0f jae SHORT $LN8@stbi__pic_ ; 1078 : return *s->img_buffer++; 00030 0f b6 08 movzx ecx, BYTE PTR [rax] 00033 48 ff c0 inc rax 00036 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0003d eb 26 jmp SHORT $LN7@stbi__pic_ $LN8@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 0003f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00043 74 1e je SHORT $LN9@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00045 48 8b cb mov rcx, rbx 00048 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0004d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00054 0f b6 08 movzx ecx, BYTE PTR [rax] 00057 48 ff c0 inc rax 0005a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00061 eb 02 jmp SHORT $LN7@stbi__pic_ $LN9@stbi__pic_: ; 1082 : } ; 1083 : return 0; 00063 32 c9 xor cl, cl $LN7@stbi__pic_: ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) 00065 3a 0c 37 cmp cl, BYTE PTR [rdi+rsi] 00068 75 1e jne SHORT $LN12@stbi__pic_ ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) 0006a 48 ff c7 inc rdi 0006d 48 83 ff 04 cmp rdi, 4 00071 7c ad jl SHORT $LL4@stbi__pic_ ; 5889 : return 0; ; 5890 : ; 5891 : return 1; 00073 b8 01 00 00 00 mov eax, 1 ; 5892 : } 00078 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0007d 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 00082 48 83 c4 20 add rsp, 32 ; 00000020H 00086 5f pop rdi 00087 c3 ret 0 $LN12@stbi__pic_: 00088 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0008d 33 c0 xor eax, eax 0008f 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 00094 48 83 c4 20 add rsp, 32 ; 00000020H 00098 5f pop rdi 00099 c3 ret 0 stbi__pic_is4 ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pic_test_core _TEXT SEGMENT s$ = 48 stbi__pic_test_core PROC ; COMDAT ; 5895 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 57 push rdi 00010 48 83 ec 20 sub rsp, 32 ; 00000020H ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) 00014 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_04KBFEPHFH@S?$IA?v4@ 0001b 48 8b d9 mov rbx, rcx 0001e e8 00 00 00 00 call stbi__pic_is4 00023 85 c0 test eax, eax 00025 0f 84 a7 00 00 00 je $LN32@stbi__pic_ ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) 0002b bf 54 00 00 00 mov edi, 84 ; 00000054H $LL4@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00030 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00037 48 8d 73 30 lea rsi, QWORD PTR [rbx+48] 0003b 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00042 73 0c jae SHORT $LN9@stbi__pic_ ; 1078 : return *s->img_buffer++; 00044 48 ff c0 inc rax 00047 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0004e eb 1b jmp SHORT $LN2@stbi__pic_ $LN9@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 00050 83 3e 00 cmp DWORD PTR [rsi], 0 00053 74 16 je SHORT $LN2@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00055 48 8b cb mov rcx, rbx 00058 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0005d 48 ff 83 c0 00 00 00 inc QWORD PTR [rbx+192] 00064 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN2@stbi__pic_: ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) 0006b 48 83 ef 01 sub rdi, 1 0006f 75 bf jne SHORT $LL4@stbi__pic_ 00071 48 8d 2d 00 00 00 00 lea rbp, OFFSET FLAT:??_C@_04ELNJHLFH@PICT@ 00078 0f 1f 84 00 00 00 00 00 npad 8 $LL15@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00080 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00087 73 0f jae SHORT $LN19@stbi__pic_ ; 1078 : return *s->img_buffer++; 00089 0f b6 08 movzx ecx, BYTE PTR [rax] 0008c 48 ff c0 inc rax 0008f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00096 eb 25 jmp SHORT $LN18@stbi__pic_ $LN19@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 00098 83 3e 00 cmp DWORD PTR [rsi], 0 0009b 74 1e je SHORT $LN20@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 0009d 48 8b cb mov rcx, rbx 000a0 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000a5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000ac 0f b6 08 movzx ecx, BYTE PTR [rax] 000af 48 ff c0 inc rax 000b2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000b9 eb 02 jmp SHORT $LN18@stbi__pic_ $LN20@stbi__pic_: ; 1082 : } ; 1083 : return 0; 000bb 32 c9 xor cl, cl $LN18@stbi__pic_: ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) 000bd 3a 0c 2f cmp cl, BYTE PTR [rdi+rbp] 000c0 75 10 jne SHORT $LN32@stbi__pic_ ; 1084 : } ; 1085 : ; 1086 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1087 : // nothing ; 1088 : #else ; 1089 : stbi_inline static int stbi__at_eof(stbi__context* s) ; 1090 : { ; 1091 : if (s->io.read) { ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) 000c2 48 ff c7 inc rdi 000c5 48 83 ff 04 cmp rdi, 4 000c9 7c b5 jl SHORT $LL15@stbi__pic_ ; 5906 : ; 5907 : return 1; 000cb b8 01 00 00 00 mov eax, 1 000d0 eb 02 jmp SHORT $LN1@stbi__pic_ $LN32@stbi__pic_: ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; 000d2 33 c0 xor eax, eax $LN1@stbi__pic_: ; 5908 : } 000d4 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000d9 48 8b 6c 24 38 mov rbp, QWORD PTR [rsp+56] 000de 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 000e3 48 83 c4 20 add rsp, 32 ; 00000020H 000e7 5f pop rdi 000e8 c3 ret 0 stbi__pic_test_core ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__readval _TEXT SEGMENT s$ = 48 channel$ = 56 dest$ = 64 stbi__readval PROC ; COMDAT ; 5916 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 56 push r14 00016 48 83 ec 20 sub rsp, 32 ; 00000020H 0001a 49 8b e8 mov rbp, r8 0001d 44 8b f2 mov r14d, edx 00020 48 8b d9 mov rbx, rcx ; 5917 : int mask = 0x80, i; 00023 be 80 00 00 00 mov esi, 128 ; 00000080H 00028 33 ff xor edi, edi 0002a 66 0f 1f 44 00 00 npad 6 $LL4@stbi__read: ; 5920 : if (channel & mask) { 00030 41 85 f6 test esi, r14d 00033 0f 84 a7 00 00 00 je $LN2@stbi__read ; 1091 : if (s->io.read) { 00039 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 0003e 74 42 je SHORT $LN25@stbi__read ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 00040 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 00044 ff 53 20 call QWORD PTR [rbx+32] 00047 85 c0 test eax, eax 00049 75 06 jne SHORT $LN10@stbi__read 0004b 48 8d 4b 30 lea rcx, QWORD PTR [rbx+48] 0004f eb 48 jmp SHORT $LN26@stbi__read $LN10@stbi__read: ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00051 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00055 48 8d 43 30 lea rax, QWORD PTR [rbx+48] 00059 75 2b jne SHORT $LN23@stbi__read $LN27@stbi__read: ; 431 : stbi__g_failure_reason = str; 0005b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00064 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 0006a ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 0006f 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 00073 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_08GGMBIFE@bad?5file@ 0007a 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); 0007e 33 c0 xor eax, eax 00080 eb 70 jmp SHORT $LN1@stbi__read $LN25@stbi__read: 00082 48 8d 43 30 lea rax, QWORD PTR [rbx+48] $LN23@stbi__read: 00086 48 8b c8 mov rcx, rax 00089 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00090 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 00097 73 c2 jae SHORT $LN27@stbi__read $LN26@stbi__read: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00099 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000a0 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000a7 73 0f jae SHORT $LN16@stbi__read ; 1078 : return *s->img_buffer++; 000a9 0f b6 08 movzx ecx, BYTE PTR [rax] 000ac 48 ff c0 inc rax 000af 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000b6 eb 25 jmp SHORT $LN15@stbi__read $LN16@stbi__read: ; 1079 : if (s->read_from_callbacks) { 000b8 83 39 00 cmp DWORD PTR [rcx], 0 000bb 74 1e je SHORT $LN17@stbi__read ; 1080 : stbi__refill_buffer(s); 000bd 48 8b cb mov rcx, rbx 000c0 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000c5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000cc 0f b6 08 movzx ecx, BYTE PTR [rax] 000cf 48 ff c0 inc rax 000d2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000d9 eb 02 jmp SHORT $LN15@stbi__read $LN17@stbi__read: ; 1082 : } ; 1083 : return 0; 000db 32 c9 xor cl, cl $LN15@stbi__read: ; 5922 : dest[i] = stbi__get8(s); 000dd 88 0c 2f mov BYTE PTR [rdi+rbp], cl $LN2@stbi__read: ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { 000e0 48 ff c7 inc rdi 000e3 d1 fe sar esi, 1 000e5 48 83 ff 04 cmp rdi, 4 000e9 0f 8c 41 ff ff ff jl $LL4@stbi__read ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; 000ef 48 8b c5 mov rax, rbp $LN1@stbi__read: ; 5927 : } 000f2 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000f7 48 8b 6c 24 38 mov rbp, QWORD PTR [rsp+56] 000fc 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 00101 48 8b 7c 24 48 mov rdi, QWORD PTR [rsp+72] 00106 48 83 c4 20 add rsp, 32 ; 00000020H 0010a 41 5e pop r14 0010c c3 ret 0 stbi__readval ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__copyval _TEXT SEGMENT channel$ = 8 dest$ = 16 src$ = 24 stbi__copyval PROC ; COMDAT ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 00000 84 c9 test cl, cl 00002 79 06 jns SHORT $LN2@stbi__copy ; 5935 : dest[i] = src[i]; 00004 41 0f b6 00 movzx eax, BYTE PTR [r8] 00008 88 02 mov BYTE PTR [rdx], al $LN2@stbi__copy: ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 0000a f6 c1 40 test cl, 64 ; 00000040H 0000d 74 08 je SHORT $LN10@stbi__copy ; 5935 : dest[i] = src[i]; 0000f 41 0f b6 40 01 movzx eax, BYTE PTR [r8+1] 00014 88 42 01 mov BYTE PTR [rdx+1], al $LN10@stbi__copy: ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 00017 f6 c1 20 test cl, 32 ; 00000020H 0001a 74 08 je SHORT $LN12@stbi__copy ; 5935 : dest[i] = src[i]; 0001c 41 0f b6 40 02 movzx eax, BYTE PTR [r8+2] 00021 88 42 02 mov BYTE PTR [rdx+2], al $LN12@stbi__copy: ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 00024 f6 c1 10 test cl, 16 00027 74 08 je SHORT $LN14@stbi__copy ; 5935 : dest[i] = src[i]; 00029 41 0f b6 40 03 movzx eax, BYTE PTR [r8+3] 0002e 88 42 03 mov BYTE PTR [rdx+3], al $LN14@stbi__copy: ; 5936 : } 00031 c3 ret 0 stbi__copyval ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pic_load_core _TEXT SEGMENT height$1$ = 32 y$1$ = 36 tv1687 = 40 $T9 = 48 $T10 = 56 result$GSCopy$1$ = 64 tv1705 = 72 value$11 = 80 value$12 = 84 packets$ = 88 __$ArrayPad$ = 120 s$ = 192 width$ = 200 height$ = 208 comp$ = 216 result$ = 224 stbi__pic_load_core PROC ; COMDAT ; 5939 : { 00000 4c 8b dc mov r11, rsp 00003 57 push rdi 00004 41 54 push r12 00006 41 55 push r13 00008 41 56 push r14 0000a 41 57 push r15 0000c 48 81 ec 90 00 00 00 sub rsp, 144 ; 00000090H 00013 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0001a 48 33 c4 xor rax, rsp 0001d 48 89 44 24 78 mov QWORD PTR __$ArrayPad$[rsp], rax 00022 48 8b 84 24 e0 00 00 00 mov rax, QWORD PTR result$[rsp] 0002a 4d 8d 73 a0 lea r14, QWORD PTR [r11-96] 0002e 49 89 5b 18 mov QWORD PTR [r11+24], rbx ; 5940 : int act_comp = 0, num_packets = 0, y, chained; 00032 45 33 ff xor r15d, r15d 00035 48 89 44 24 40 mov QWORD PTR result$GSCopy$1$[rsp], rax 0003a 4d 8b e1 mov r12, r9 0003d 49 89 6b d0 mov QWORD PTR [r11-48], rbp 00041 33 c0 xor eax, eax 00043 44 89 44 24 20 mov DWORD PTR height$1$[rsp], r8d 00048 44 8b ea mov r13d, edx 0004b 48 8b f9 mov rdi, rcx 0004e 49 89 73 c8 mov QWORD PTR [r11-56], rsi $LL4@stbi__pic_: ; 5941 : stbi__pic_packet packets[10]; ; 5942 : ; 5943 : // this will (should...) cater for even some bizarre stuff like having data ; 5944 : // for the same channel in multiple packets. ; 5945 : do { ; 5946 : stbi__pic_packet* packet; ; 5947 : ; 5948 : if (num_packets == sizeof(packets) / sizeof(packets[0])) 00052 48 83 f8 0a cmp rax, 10 00056 0f 84 19 05 00 00 je $LN128@stbi__pic_ ; 5949 : return stbi__errpuc("bad format", "too many packets"); ; 5950 : ; 5951 : packet = &packets[num_packets++]; 0005c 48 ff c0 inc rax 0005f 49 8b f6 mov rsi, r14 00062 48 89 44 24 30 mov QWORD PTR $T9[rsp], rax 00067 49 83 c6 03 add r14, 3 ; 1077 : if (s->img_buffer < s->img_buffer_end) 0006b 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00072 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00079 73 0f jae SHORT $LN57@stbi__pic_ ; 1078 : return *s->img_buffer++; 0007b 0f b6 28 movzx ebp, BYTE PTR [rax] 0007e 48 ff c0 inc rax 00081 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00088 eb 27 jmp SHORT $LN56@stbi__pic_ $LN57@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 0008a 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0008e 74 1e je SHORT $LN58@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00090 48 8b cf mov rcx, rdi 00093 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00098 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0009f 0f b6 28 movzx ebp, BYTE PTR [rax] 000a2 48 ff c0 inc rax 000a5 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 000ac eb 03 jmp SHORT $LN56@stbi__pic_ $LN58@stbi__pic_: ; 1082 : } ; 1083 : return 0; 000ae 40 32 ed xor bpl, bpl $LN56@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 000b1 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 000b8 73 0f jae SHORT $LN61@stbi__pic_ ; 1078 : return *s->img_buffer++; 000ba 0f b6 18 movzx ebx, BYTE PTR [rax] 000bd 48 ff c0 inc rax 000c0 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 000c7 eb 26 jmp SHORT $LN60@stbi__pic_ $LN61@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 000c9 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 000cd 74 1e je SHORT $LN62@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 000cf 48 8b cf mov rcx, rdi 000d2 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000d7 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 000de 0f b6 18 movzx ebx, BYTE PTR [rax] 000e1 48 ff c0 inc rax 000e4 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 000eb eb 02 jmp SHORT $LN60@stbi__pic_ $LN62@stbi__pic_: ; 1082 : } ; 1083 : return 0; 000ed 32 db xor bl, bl $LN60@stbi__pic_: ; 5952 : ; 5953 : chained = stbi__get8(s); ; 5954 : packet->size = stbi__get8(s); 000ef 88 1e mov BYTE PTR [rsi], bl ; 1077 : if (s->img_buffer < s->img_buffer_end) 000f1 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 000f8 73 0f jae SHORT $LN65@stbi__pic_ ; 1078 : return *s->img_buffer++; 000fa 0f b6 08 movzx ecx, BYTE PTR [rax] 000fd 48 ff c0 inc rax 00100 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00107 eb 26 jmp SHORT $LN64@stbi__pic_ $LN65@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 00109 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0010d 74 1e je SHORT $LN66@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 0010f 48 8b cf mov rcx, rdi 00112 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00117 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0011e 0f b6 08 movzx ecx, BYTE PTR [rax] 00121 48 ff c0 inc rax 00124 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0012b eb 02 jmp SHORT $LN64@stbi__pic_ $LN66@stbi__pic_: ; 1082 : } ; 1083 : return 0; 0012d 32 c9 xor cl, cl $LN64@stbi__pic_: ; 5955 : packet->type = stbi__get8(s); 0012f 88 4e 01 mov BYTE PTR [rsi+1], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00132 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 00139 73 0f jae SHORT $LN69@stbi__pic_ ; 1078 : return *s->img_buffer++; 0013b 0f b6 08 movzx ecx, BYTE PTR [rax] 0013e 48 ff c0 inc rax 00141 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00148 eb 26 jmp SHORT $LN68@stbi__pic_ $LN69@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 0014a 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0014e 74 1e je SHORT $LN70@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00150 48 8b cf mov rcx, rdi 00153 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00158 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 0015f 0f b6 08 movzx ecx, BYTE PTR [rax] 00162 48 ff c0 inc rax 00165 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0016c eb 02 jmp SHORT $LN68@stbi__pic_ $LN70@stbi__pic_: ; 1082 : } ; 1083 : return 0; 0016e 32 c9 xor cl, cl $LN68@stbi__pic_: ; 5956 : packet->channel = stbi__get8(s); ; 5957 : ; 5958 : act_comp |= packet->channel; 00170 0f b6 c1 movzx eax, cl 00173 44 0b f8 or r15d, eax 00176 88 4e 02 mov BYTE PTR [rsi+2], cl ; 1091 : if (s->io.read) { 00179 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 0017e 74 15 je SHORT $LN190@stbi__pic_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 00180 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 00184 ff 57 20 call QWORD PTR [rdi+32] 00187 85 c0 test eax, eax 00189 74 1e je SHORT $LN196@stbi__pic_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 0018b 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0018f 0f 84 c4 03 00 00 je $LN134@stbi__pic_ $LN190@stbi__pic_: ; 5959 : ; 5960 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (reading packets)"); 00195 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 0019c 48 39 87 c0 00 00 00 cmp QWORD PTR [rdi+192], rax 001a3 0f 83 b0 03 00 00 jae $LN134@stbi__pic_ $LN196@stbi__pic_: ; 5961 : if (packet->size != 8) return stbi__errpuc("bad format", "packet isn't 8bpp"); 001a9 80 fb 08 cmp bl, 8 001ac 0f 85 c3 03 00 00 jne $LN128@stbi__pic_ ; 5962 : } while (chained); 001b2 48 8b 44 24 30 mov rax, QWORD PTR $T9[rsp] 001b7 40 84 ed test bpl, bpl 001ba 0f 85 92 fe ff ff jne $LL4@stbi__pic_ ; 5963 : ; 5964 : *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? 001c0 41 f6 c7 10 test r15b, 16 001c4 b8 00 00 00 00 mov eax, 0 001c9 0f 95 c0 setne al ; 5965 : ; 5966 : for (y = 0; y < height; ++y) { 001cc 33 c9 xor ecx, ecx 001ce 83 c0 03 add eax, 3 001d1 89 4c 24 24 mov DWORD PTR y$1$[rsp], ecx 001d5 41 89 04 24 mov DWORD PTR [r12], eax 001d9 39 4c 24 20 cmp DWORD PTR height$1$[rsp], ecx 001dd 0f 8e 6f 03 00 00 jle $LN202@stbi__pic_ ; 5963 : ; 5964 : *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? 001e3 48 8b 44 24 30 mov rax, QWORD PTR $T9[rsp] 001e8 46 8d 04 ad 00 00 00 00 lea r8d, DWORD PTR [r13*4] 001f0 44 8b 4c 24 20 mov r9d, DWORD PTR height$1$[rsp] 001f5 33 d2 xor edx, edx 001f7 89 54 24 28 mov DWORD PTR tv1687[rsp], edx 001fb 0f 1f 44 00 00 npad 5 $LL7@stbi__pic_: ; 5967 : int packet_idx; ; 5968 : ; 5969 : for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) { 00200 48 c7 44 24 38 00 00 00 00 mov QWORD PTR $T10[rsp], 0 00209 48 85 c0 test rax, rax 0020c 0f 8e 2a 03 00 00 jle $LN5@stbi__pic_ 00212 48 63 c2 movsxd rax, edx 00215 4c 8d 64 24 5a lea r12, QWORD PTR packets$[rsp+2] 0021a 48 03 44 24 40 add rax, QWORD PTR result$GSCopy$1$[rsp] 0021f 48 89 44 24 48 mov QWORD PTR tv1705[rsp], rax $LL10@stbi__pic_: ; 5970 : stbi__pic_packet* packet = &packets[packet_idx]; ; 5971 : stbi_uc* dest = result + y * width * 4; ; 5972 : ; 5973 : switch (packet->type) { 00224 41 0f b6 4c 24 ff movzx ecx, BYTE PTR [r12-1] 0022a 48 8b d8 mov rbx, rax 0022d 85 c9 test ecx, ecx 0022f 0f 84 9e 02 00 00 je $LN33@stbi__pic_ 00235 83 e9 01 sub ecx, 1 00238 0f 84 84 01 00 00 je $LN35@stbi__pic_ 0023e 83 f9 01 cmp ecx, 1 00241 0f 85 2e 03 00 00 jne $LN128@stbi__pic_ ; 6004 : } ; 6005 : } ; 6006 : break; ; 6007 : ; 6008 : case 2: {//Mixed RLE ; 6009 : int left = width; 00247 45 8b fd mov r15d, r13d ; 6010 : while (left > 0) { 0024a 45 85 ed test r13d, r13d 0024d 0f 8e ae 02 00 00 jle $LN8@stbi__pic_ 00253 0f 1f 40 00 66 0f 1f 84 00 00 00 00 00 npad 13 $LL21@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00260 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00267 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0026e 73 0f jae SHORT $LN87@stbi__pic_ ; 1078 : return *s->img_buffer++; 00270 0f b6 08 movzx ecx, BYTE PTR [rax] 00273 48 ff c0 inc rax 00276 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0027d eb 26 jmp SHORT $LN86@stbi__pic_ $LN87@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 0027f 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 00283 74 1e je SHORT $LN88@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00285 48 8b cf mov rcx, rdi 00288 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0028d 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00294 0f b6 08 movzx ecx, BYTE PTR [rax] 00297 48 ff c0 inc rax 0029a 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 002a1 eb 02 jmp SHORT $LN86@stbi__pic_ $LN88@stbi__pic_: ; 1082 : } ; 1083 : return 0; 002a3 32 c9 xor cl, cl $LN86@stbi__pic_: ; 1091 : if (s->io.read) { 002a5 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 ; 6011 : int count = stbi__get8(s), i; 002aa 0f b6 e9 movzx ebp, cl ; 1091 : if (s->io.read) { 002ad 74 15 je SHORT $LN192@stbi__pic_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 002af 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 002b3 ff 57 20 call QWORD PTR [rdi+32] 002b6 85 c0 test eax, eax 002b8 74 1e je SHORT $LN195@stbi__pic_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 002ba 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 002be 0f 84 95 02 00 00 je $LN134@stbi__pic_ $LN192@stbi__pic_: ; 6012 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (mixed read count)"); 002c4 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 002cb 48 39 87 c0 00 00 00 cmp QWORD PTR [rdi+192], rax 002d2 0f 83 81 02 00 00 jae $LN134@stbi__pic_ $LN195@stbi__pic_: ; 6013 : ; 6014 : if (count >= 128) { // Repeated 002d8 81 fd 80 00 00 00 cmp ebp, 128 ; 00000080H 002de 0f 82 8c 00 00 00 jb $LN41@stbi__pic_ ; 6015 : stbi_uc value[4]; ; 6016 : ; 6017 : if (count == 128) 002e4 75 0c jne SHORT $LN43@stbi__pic_ ; 6018 : count = stbi__get16be(s); 002e6 48 8b cf mov rcx, rdi 002e9 e8 00 00 00 00 call stbi__get16be 002ee 8b e8 mov ebp, eax 002f0 eb 03 jmp SHORT $LN44@stbi__pic_ $LN43@stbi__pic_: ; 6019 : else ; 6020 : count -= 127; 002f2 83 ed 7f sub ebp, 127 ; 0000007fH $LN44@stbi__pic_: ; 6021 : if (count > left) 002f5 41 3b ef cmp ebp, r15d 002f8 0f 8f 5b 02 00 00 jg $LN134@stbi__pic_ ; 6022 : return stbi__errpuc("bad file", "scanline overrun"); ; 6023 : ; 6024 : if (!stbi__readval(s, packet->channel, value)) 002fe 41 0f b6 34 24 movzx esi, BYTE PTR [r12] 00303 4c 8d 44 24 50 lea r8, QWORD PTR value$11[rsp] 00308 8b d6 mov edx, esi 0030a 48 8b cf mov rcx, rdi 0030d e8 00 00 00 00 call stbi__readval 00312 48 85 c0 test rax, rax 00315 0f 84 7d 02 00 00 je $LN139@stbi__pic_ ; 6025 : return 0; ; 6026 : ; 6027 : for (i = 0; i < count; ++i, dest += 4) 0031b 85 ed test ebp, ebp 0031d 0f 8e 8e 00 00 00 jle $LN27@stbi__pic_ ; 6028 : stbi__copyval(packet->channel, dest, value); 00323 8b 44 24 50 mov eax, DWORD PTR value$11[rsp] 00327 0f b6 54 24 53 movzx edx, BYTE PTR value$11[rsp+3] 0032c 44 0f b6 44 24 52 movzx r8d, BYTE PTR value$11[rsp+2] 00332 44 0f b6 4c 24 51 movzx r9d, BYTE PTR value$11[rsp+1] 00338 8b cd mov ecx, ebp 0033a 66 0f 1f 44 00 00 npad 6 $LL25@stbi__pic_: ; 5934 : if (channel & mask) 00340 40 84 f6 test sil, sil 00343 79 02 jns SHORT $LN100@stbi__pic_ ; 5935 : dest[i] = src[i]; 00345 88 03 mov BYTE PTR [rbx], al $LN100@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 00347 40 f6 c6 40 test sil, 64 ; 00000040H 0034b 74 04 je SHORT $LN151@stbi__pic_ ; 5935 : dest[i] = src[i]; 0034d 44 88 4b 01 mov BYTE PTR [rbx+1], r9b $LN151@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 00351 40 f6 c6 20 test sil, 32 ; 00000020H 00355 74 04 je SHORT $LN153@stbi__pic_ ; 5935 : dest[i] = src[i]; 00357 44 88 43 02 mov BYTE PTR [rbx+2], r8b $LN153@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 0035b 40 f6 c6 10 test sil, 16 0035f 74 03 je SHORT $LN155@stbi__pic_ ; 5935 : dest[i] = src[i]; 00361 88 53 03 mov BYTE PTR [rbx+3], dl $LN155@stbi__pic_: ; 6025 : return 0; ; 6026 : ; 6027 : for (i = 0; i < count; ++i, dest += 4) 00364 48 83 c3 04 add rbx, 4 00368 48 83 e9 01 sub rcx, 1 0036c 75 d2 jne SHORT $LL25@stbi__pic_ ; 6029 : } 0036e eb 41 jmp SHORT $LN27@stbi__pic_ $LN41@stbi__pic_: ; 6030 : else { // Raw ; 6031 : ++count; 00370 ff c5 inc ebp ; 6032 : if (count > left) return stbi__errpuc("bad file", "scanline overrun"); 00372 41 3b ef cmp ebp, r15d 00375 0f 87 de 01 00 00 ja $LN134@stbi__pic_ ; 6033 : ; 6034 : for (i = 0; i < count; ++i, dest += 4) 0037b 33 f6 xor esi, esi 0037d 85 ed test ebp, ebp 0037f 74 30 je SHORT $LN27@stbi__pic_ 00381 45 0f b6 34 24 movzx r14d, BYTE PTR [r12] 00386 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL28@stbi__pic_: ; 6035 : if (!stbi__readval(s, packet->channel, dest)) 00390 4c 8b c3 mov r8, rbx 00393 41 8b d6 mov edx, r14d 00396 48 8b cf mov rcx, rdi 00399 e8 00 00 00 00 call stbi__readval 0039e 48 85 c0 test rax, rax 003a1 0f 84 f1 01 00 00 je $LN139@stbi__pic_ ; 6033 : ; 6034 : for (i = 0; i < count; ++i, dest += 4) 003a7 ff c6 inc esi 003a9 48 83 c3 04 add rbx, 4 003ad 3b f5 cmp esi, ebp 003af 7c df jl SHORT $LL28@stbi__pic_ $LN27@stbi__pic_: ; 6036 : return 0; ; 6037 : } ; 6038 : left -= count; 003b1 44 2b fd sub r15d, ebp 003b4 45 85 ff test r15d, r15d 003b7 0f 8f a3 fe ff ff jg $LL21@stbi__pic_ ; 5981 : if (!stbi__readval(s, packet->channel, dest)) 003bd e9 3f 01 00 00 jmp $LN8@stbi__pic_ $LN35@stbi__pic_: ; 5982 : return 0; ; 5983 : break; ; 5984 : } ; 5985 : ; 5986 : case 1://Pure RLE ; 5987 : { ; 5988 : int left = width, i; 003c2 45 8b f5 mov r14d, r13d ; 5989 : ; 5990 : while (left > 0) { 003c5 45 85 ed test r13d, r13d 003c8 0f 8e 33 01 00 00 jle $LN8@stbi__pic_ 003ce 66 90 npad 2 $LL16@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 003d0 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 003d7 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 003de 73 0f jae SHORT $LN78@stbi__pic_ ; 1078 : return *s->img_buffer++; 003e0 0f b6 30 movzx esi, BYTE PTR [rax] 003e3 48 ff c0 inc rax 003e6 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 003ed eb 27 jmp SHORT $LN77@stbi__pic_ $LN78@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 003ef 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 003f3 74 1e je SHORT $LN79@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 003f5 48 8b cf mov rcx, rdi 003f8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003fd 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00404 0f b6 30 movzx esi, BYTE PTR [rax] 00407 48 ff c0 inc rax 0040a 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00411 eb 03 jmp SHORT $LN77@stbi__pic_ $LN79@stbi__pic_: ; 1082 : } ; 1083 : return 0; 00413 40 32 f6 xor sil, sil $LN77@stbi__pic_: ; 1091 : if (s->io.read) { 00416 48 83 7f 10 00 cmp QWORD PTR [rdi+16], 0 0041b 74 15 je SHORT $LN193@stbi__pic_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0041d 48 8b 4f 28 mov rcx, QWORD PTR [rdi+40] 00421 ff 57 20 call QWORD PTR [rdi+32] 00424 85 c0 test eax, eax 00426 74 1e je SHORT $LN194@stbi__pic_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00428 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0042c 0f 84 27 01 00 00 je $LN134@stbi__pic_ $LN193@stbi__pic_: ; 5991 : stbi_uc count, value[4]; ; 5992 : ; 5993 : count = stbi__get8(s); ; 5994 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pure read count)"); 00432 48 8b 87 c8 00 00 00 mov rax, QWORD PTR [rdi+200] 00439 48 39 87 c0 00 00 00 cmp QWORD PTR [rdi+192], rax 00440 0f 83 13 01 00 00 jae $LN134@stbi__pic_ $LN194@stbi__pic_: ; 5995 : ; 5996 : if (count > left) 00446 40 0f b6 ce movzx ecx, sil ; 5997 : count = (stbi_uc)left; ; 5998 : ; 5999 : if (!stbi__readval(s, packet->channel, value)) return 0; 0044a 4c 8d 44 24 54 lea r8, QWORD PTR value$12[rsp] 0044f 41 3b ce cmp ecx, r14d 00452 40 0f b6 ee movzx ebp, sil 00456 41 0f b6 34 24 movzx esi, BYTE PTR [r12] 0045b 48 8b cf mov rcx, rdi 0045e 41 0f b6 c6 movzx eax, r14b 00462 8b d6 mov edx, esi 00464 0f 47 e8 cmova ebp, eax 00467 e8 00 00 00 00 call stbi__readval 0046c 48 85 c0 test rax, rax 0046f 0f 84 23 01 00 00 je $LN139@stbi__pic_ ; 6000 : ; 6001 : for (i = 0; i < count; ++i, dest += 4) 00475 40 84 ed test bpl, bpl 00478 74 47 je SHORT $LN19@stbi__pic_ ; 6002 : stbi__copyval(packet->channel, dest, value); 0047a 8b 44 24 54 mov eax, DWORD PTR value$12[rsp] 0047e 0f b6 54 24 57 movzx edx, BYTE PTR value$12[rsp+3] 00483 44 0f b6 44 24 56 movzx r8d, BYTE PTR value$12[rsp+2] 00489 44 0f b6 4c 24 55 movzx r9d, BYTE PTR value$12[rsp+1] 0048f 40 0f b6 cd movzx ecx, bpl $LL20@stbi__pic_: ; 5934 : if (channel & mask) 00493 40 84 f6 test sil, sil 00496 79 02 jns SHORT $LN51@stbi__pic_ ; 5935 : dest[i] = src[i]; 00498 88 03 mov BYTE PTR [rbx], al $LN51@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 0049a 40 f6 c6 40 test sil, 64 ; 00000040H 0049e 74 04 je SHORT $LN157@stbi__pic_ ; 5935 : dest[i] = src[i]; 004a0 44 88 4b 01 mov BYTE PTR [rbx+1], r9b $LN157@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 004a4 40 f6 c6 20 test sil, 32 ; 00000020H 004a8 74 04 je SHORT $LN159@stbi__pic_ ; 5935 : dest[i] = src[i]; 004aa 44 88 43 02 mov BYTE PTR [rbx+2], r8b $LN159@stbi__pic_: ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) 004ae 40 f6 c6 10 test sil, 16 004b2 74 03 je SHORT $LN161@stbi__pic_ ; 5935 : dest[i] = src[i]; 004b4 88 53 03 mov BYTE PTR [rbx+3], dl $LN161@stbi__pic_: ; 6000 : ; 6001 : for (i = 0; i < count; ++i, dest += 4) 004b7 48 83 c3 04 add rbx, 4 004bb 48 83 e9 01 sub rcx, 1 004bf 75 d2 jne SHORT $LL20@stbi__pic_ $LN19@stbi__pic_: ; 6003 : left -= count; 004c1 40 0f b6 c5 movzx eax, bpl 004c5 44 2b f0 sub r14d, eax 004c8 45 85 f6 test r14d, r14d 004cb 0f 8f ff fe ff ff jg $LL16@stbi__pic_ ; 5989 : ; 5990 : while (left > 0) { 004d1 eb 2e jmp SHORT $LN8@stbi__pic_ $LN33@stbi__pic_: ; 5974 : default: ; 5975 : return stbi__errpuc("bad format", "packet has bad compression type"); ; 5976 : ; 5977 : case 0: {//uncompressed ; 5978 : int x; ; 5979 : ; 5980 : for (x = 0; x < width; ++x, dest += 4) 004d3 33 f6 xor esi, esi 004d5 45 85 ed test r13d, r13d 004d8 7e 27 jle SHORT $LN8@stbi__pic_ 004da 41 0f b6 2c 24 movzx ebp, BYTE PTR [r12] 004df 90 npad 1 $LL15@stbi__pic_: ; 5981 : if (!stbi__readval(s, packet->channel, dest)) 004e0 4c 8b c3 mov r8, rbx 004e3 8b d5 mov edx, ebp 004e5 48 8b cf mov rcx, rdi 004e8 e8 00 00 00 00 call stbi__readval 004ed 48 85 c0 test rax, rax 004f0 0f 84 a2 00 00 00 je $LN139@stbi__pic_ ; 5974 : default: ; 5975 : return stbi__errpuc("bad format", "packet has bad compression type"); ; 5976 : ; 5977 : case 0: {//uncompressed ; 5978 : int x; ; 5979 : ; 5980 : for (x = 0; x < width; ++x, dest += 4) 004f6 ff c6 inc esi 004f8 48 83 c3 04 add rbx, 4 004fc 41 3b f5 cmp esi, r13d 004ff 7c df jl SHORT $LL15@stbi__pic_ $LN8@stbi__pic_: ; 5967 : int packet_idx; ; 5968 : ; 5969 : for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) { 00501 48 8b 44 24 38 mov rax, QWORD PTR $T10[rsp] 00506 49 83 c4 03 add r12, 3 0050a 48 ff c0 inc rax 0050d 48 3b 44 24 30 cmp rax, QWORD PTR $T9[rsp] 00512 48 89 44 24 38 mov QWORD PTR $T10[rsp], rax 00517 48 8b 44 24 48 mov rax, QWORD PTR tv1705[rsp] 0051c 0f 8c 02 fd ff ff jl $LL10@stbi__pic_ 00522 48 8b 44 24 30 mov rax, QWORD PTR $T9[rsp] 00527 46 8d 04 ad 00 00 00 00 lea r8d, DWORD PTR [r13*4] 0052f 8b 4c 24 24 mov ecx, DWORD PTR y$1$[rsp] 00533 8b 54 24 28 mov edx, DWORD PTR tv1687[rsp] 00537 44 8b 4c 24 20 mov r9d, DWORD PTR height$1$[rsp] $LN5@stbi__pic_: ; 5965 : ; 5966 : for (y = 0; y < height; ++y) { 0053c ff c1 inc ecx 0053e 41 03 d0 add edx, r8d 00541 89 4c 24 24 mov DWORD PTR y$1$[rsp], ecx 00545 89 54 24 28 mov DWORD PTR tv1687[rsp], edx 00549 41 3b c9 cmp ecx, r9d 0054c 0f 8c ae fc ff ff jl $LL7@stbi__pic_ $LN202@stbi__pic_: ; 6039 : } ; 6040 : break; ; 6041 : } ; 6042 : } ; 6043 : } ; 6044 : } ; 6045 : ; 6046 : return result; 00552 48 8b 44 24 40 mov rax, QWORD PTR result$GSCopy$1$[rsp] 00557 eb 41 jmp SHORT $LN1@stbi__pic_ $LN134@stbi__pic_: ; 6047 : } 00559 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0055f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00568 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0056c 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08GGMBIFE@bad?5file@ 00573 eb 1a jmp SHORT $LN260@stbi__pic_ $LN128@stbi__pic_: 00575 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0057b 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00584 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00588 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@DMAPJJO@bad?5format@ $LN260@stbi__pic_: 0058f b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00594 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN139@stbi__pic_: 00598 33 c0 xor eax, eax $LN1@stbi__pic_: 0059a 48 8b b4 24 80 00 00 00 mov rsi, QWORD PTR [rsp+128] 005a2 48 8b ac 24 88 00 00 00 mov rbp, QWORD PTR [rsp+136] 005aa 48 8b 9c 24 d0 00 00 00 mov rbx, QWORD PTR [rsp+208] 005b2 48 8b 4c 24 78 mov rcx, QWORD PTR __$ArrayPad$[rsp] 005b7 48 33 cc xor rcx, rsp 005ba e8 00 00 00 00 call __security_check_cookie 005bf 48 81 c4 90 00 00 00 add rsp, 144 ; 00000090H 005c6 41 5f pop r15 005c8 41 5e pop r14 005ca 41 5d pop r13 005cc 41 5c pop r12 005ce 5f pop rdi 005cf c3 ret 0 stbi__pic_load_core ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pic_load _TEXT SEGMENT py$GSCopy$1$ = 48 internal_comp$ = 56 __$ArrayPad$ = 64 s$ = 160 px$ = 168 py$ = 176 comp$ = 184 req_comp$ = 192 ri$dead$ = 200 stbi__pic_load PROC ; COMDAT ; 6050 : { 00000 40 53 push rbx 00002 56 push rsi 00003 57 push rdi 00004 41 54 push r12 00006 41 55 push r13 00008 41 57 push r15 0000a 48 83 ec 68 sub rsp, 104 ; 00000068H 0000e 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00015 48 33 c4 xor rax, rsp 00018 48 89 44 24 40 mov QWORD PTR __$ArrayPad$[rsp], rax 0001d 44 8b bc 24 c0 00 00 00 mov r15d, DWORD PTR req_comp$[rsp] ; 6051 : stbi_uc* result; ; 6052 : int i, x, y, internal_comp; ; 6053 : STBI_NOTUSED(ri); ; 6054 : ; 6055 : if (!comp) comp = &internal_comp; ; 6056 : ; 6057 : for (i = 0; i < 92; ++i) 00025 4c 8d 64 24 38 lea r12, QWORD PTR internal_comp$[rsp] 0002a 4d 85 c9 test r9, r9 0002d 4c 89 44 24 30 mov QWORD PTR py$GSCopy$1$[rsp], r8 00032 4c 8b ea mov r13, rdx 00035 48 8b d9 mov rbx, rcx 00038 4d 0f 45 e1 cmovne r12, r9 0003c bf 5c 00 00 00 mov edi, 92 ; 0000005cH 00041 0f 1f 40 00 66 66 66 0f 1f 84 00 00 00 00 00 npad 15 $LL4@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00050 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00057 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0005e 73 0c jae SHORT $LN15@stbi__pic_ ; 1078 : return *s->img_buffer++; 00060 48 ff c0 inc rax 00063 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0006a eb 15 jmp SHORT $LN2@stbi__pic_ $LN15@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 0006c 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00070 74 0f je SHORT $LN2@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 00072 48 8b cb mov rcx, rbx 00075 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0007a 48 ff 83 c0 00 00 00 inc QWORD PTR [rbx+192] $LN2@stbi__pic_: ; 6051 : stbi_uc* result; ; 6052 : int i, x, y, internal_comp; ; 6053 : STBI_NOTUSED(ri); ; 6054 : ; 6055 : if (!comp) comp = &internal_comp; ; 6056 : ; 6057 : for (i = 0; i < 92; ++i) 00081 48 83 ef 01 sub rdi, 1 00085 75 c9 jne SHORT $LL4@stbi__pic_ ; 6058 : stbi__get8(s); ; 6059 : ; 6060 : x = stbi__get16be(s); 00087 48 8b cb mov rcx, rbx 0008a e8 00 00 00 00 call stbi__get16be ; 6061 : y = stbi__get16be(s); 0008f 48 8b cb mov rcx, rbx 00092 8b f0 mov esi, eax 00094 e8 00 00 00 00 call stbi__get16be 00099 8b f8 mov edi, eax ; 6062 : ; 6063 : if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0009b 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 000a0 7e 2a jle SHORT $LN6@stbi__pic_ $LN108@stbi__pic_: ; 6088 : } 000a2 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 000a8 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000b1 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 000b6 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 000ba 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 000c1 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 000c5 33 c0 xor eax, eax 000c7 e9 7c 01 00 00 jmp $LN1@stbi__pic_ $LN6@stbi__pic_: ; 6064 : if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 000cc 81 fe 00 00 00 01 cmp esi, 16777216 ; 01000000H 000d2 7f ce jg SHORT $LN108@stbi__pic_ ; 1091 : if (s->io.read) { 000d4 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 000d9 74 11 je SHORT $LN25@stbi__pic_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 000db 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 000df ff 53 20 call QWORD PTR [rbx+32] 000e2 85 c0 test eax, eax 000e4 74 40 je SHORT $LN8@stbi__pic_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 000e6 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000ea 74 10 je SHORT $LN85@stbi__pic_ $LN25@stbi__pic_: ; 6065 : ; 6066 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); 000ec 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 000f3 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 000fa 72 2a jb SHORT $LN8@stbi__pic_ $LN85@stbi__pic_: ; 431 : stbi__g_failure_reason = str; 000fc 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00102 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0010b b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00110 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00114 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08GGMBIFE@bad?5file@ 0011b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 6065 : ; 6066 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); 0011f 33 c0 xor eax, eax 00121 e9 22 01 00 00 jmp $LN1@stbi__pic_ $LN8@stbi__pic_: ; 467 : if (a < 0 || b < 0) return 0; 00126 85 f6 test esi, esi 00128 0f 88 74 ff ff ff js $LN108@stbi__pic_ 0012e 85 ff test edi, edi 00130 0f 88 6c ff ff ff js $LN108@stbi__pic_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00136 74 10 je SHORT $LN84@stbi__pic_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00138 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0013d 99 cdq 0013e f7 ff idiv edi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00140 3b f0 cmp esi, eax 00142 0f 8f 5a ff ff ff jg $LN108@stbi__pic_ $LN84@stbi__pic_: 00148 8b cf mov ecx, edi 0014a 0f af ce imul ecx, esi ; 467 : if (a < 0 || b < 0) return 0; 0014d 85 c9 test ecx, ecx 0014f 0f 88 4d ff ff ff js $LN108@stbi__pic_ ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00155 81 f9 ff ff ff 1f cmp ecx, 536870911 ; 1fffffffH 0015b 0f 8f 41 ff ff ff jg $LN108@stbi__pic_ 00161 48 89 6c 24 60 mov QWORD PTR [rsp+96], rbp 00166 48 8b cb mov rcx, rbx 00169 4c 89 74 24 58 mov QWORD PTR [rsp+88], r14 0016e e8 00 00 00 00 call stbi__get16be 00173 48 8b cb mov rcx, rbx 00176 e8 00 00 00 00 call stbi__get16be 0017b 48 8b cb mov rcx, rbx 0017e e8 00 00 00 00 call stbi__get16be 00183 48 8b cb mov rcx, rbx 00186 e8 00 00 00 00 call stbi__get16be ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0018b 85 ff test edi, edi 0018d 74 0c je SHORT $LN51@stbi__pic_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0018f b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00194 99 cdq 00195 f7 ff idiv edi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00197 3b f0 cmp esi, eax 00199 7f 7e jg SHORT $LN79@stbi__pic_ $LN51@stbi__pic_: ; 509 : return stbi__malloc(a * b * c + add); 0019b 8b c7 mov eax, edi 0019d 0f af c6 imul eax, esi 001a0 c1 e0 02 shl eax, 2 001a3 4c 63 f0 movsxd r14, eax ; 438 : return STBI_MALLOC(size); 001a6 49 8b ce mov rcx, r14 001a9 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 001af 48 8b e8 mov rbp, rax ; 6067 : if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); ; 6068 : ; 6069 : stbi__get32be(s); //skip `ratio' ; 6070 : stbi__get16be(s); //skip `fields' ; 6071 : stbi__get16be(s); //skip `pad' ; 6072 : ; 6073 : // intermediate buffer is RGBA ; 6074 : result = (stbi_uc*)stbi__malloc_mad3(x, y, 4, 0); ; 6075 : if (!result) return stbi__errpuc("outofmem", "Out of memory"); 001b2 48 85 c0 test rax, rax 001b5 74 62 je SHORT $LN79@stbi__pic_ ; 6076 : memset(result, 0xff, x * y * 4); 001b7 4d 8b c6 mov r8, r14 001ba ba ff 00 00 00 mov edx, 255 ; 000000ffH 001bf 48 8b c8 mov rcx, rax 001c2 e8 00 00 00 00 call memset ; 6077 : ; 6078 : if (!stbi__pic_load_core(s, x, y, comp, result)) { 001c7 4d 8b cc mov r9, r12 001ca 48 89 6c 24 20 mov QWORD PTR [rsp+32], rbp 001cf 44 8b c7 mov r8d, edi 001d2 8b d6 mov edx, esi 001d4 48 8b cb mov rcx, rbx 001d7 e8 00 00 00 00 call stbi__pic_load_core 001dc 48 85 c0 test rax, rax 001df 75 0b jne SHORT $LN11@stbi__pic_ ; 6079 : STBI_FREE(result); 001e1 48 8b cd mov rcx, rbp 001e4 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 6080 : result = 0; 001ea 33 ed xor ebp, ebp $LN11@stbi__pic_: ; 6081 : } ; 6082 : *px = x; ; 6083 : *py = y; 001ec 48 8b 44 24 30 mov rax, QWORD PTR py$GSCopy$1$[rsp] 001f1 41 89 75 00 mov DWORD PTR [r13], esi 001f5 89 38 mov DWORD PTR [rax], edi ; 6084 : if (req_comp == 0) req_comp = *comp; 001f7 45 85 ff test r15d, r15d 001fa 75 04 jne SHORT $LN12@stbi__pic_ 001fc 45 8b 3c 24 mov r15d, DWORD PTR [r12] $LN12@stbi__pic_: ; 6085 : result = stbi__convert_format(result, 4, req_comp, x, y); 00200 44 8b ce mov r9d, esi 00203 89 7c 24 20 mov DWORD PTR [rsp+32], edi 00207 45 8b c7 mov r8d, r15d 0020a ba 04 00 00 00 mov edx, 4 0020f 48 8b cd mov rcx, rbp 00212 e8 00 00 00 00 call stbi__convert_format ; 6086 : ; 6087 : return result; 00217 eb 25 jmp SHORT $LN107@stbi__pic_ $LN79@stbi__pic_: ; 431 : stbi__g_failure_reason = str; 00219 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0021f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00228 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0022d 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00231 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 00238 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 6067 : if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); ; 6068 : ; 6069 : stbi__get32be(s); //skip `ratio' ; 6070 : stbi__get16be(s); //skip `fields' ; 6071 : stbi__get16be(s); //skip `pad' ; 6072 : ; 6073 : // intermediate buffer is RGBA ; 6074 : result = (stbi_uc*)stbi__malloc_mad3(x, y, 4, 0); ; 6075 : if (!result) return stbi__errpuc("outofmem", "Out of memory"); 0023c 33 c0 xor eax, eax $LN107@stbi__pic_: 0023e 48 8b 6c 24 60 mov rbp, QWORD PTR [rsp+96] 00243 4c 8b 74 24 58 mov r14, QWORD PTR [rsp+88] $LN1@stbi__pic_: ; 6088 : } 00248 48 8b 4c 24 40 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0024d 48 33 cc xor rcx, rsp 00250 e8 00 00 00 00 call __security_check_cookie 00255 48 83 c4 68 add rsp, 104 ; 00000068H 00259 41 5f pop r15 0025b 41 5d pop r13 0025d 41 5c pop r12 0025f 5f pop rdi 00260 5e pop rsi 00261 5b pop rbx 00262 c3 ret 0 stbi__pic_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pic_test _TEXT SEGMENT s$ = 64 stbi__pic_test PROC ; COMDAT ; 6091 : { 00000 48 89 5c 24 20 mov QWORD PTR [rsp+32], rbx 00005 55 push rbp 00006 41 56 push r14 00008 41 57 push r15 0000a 48 83 ec 20 sub rsp, 32 ; 00000020H ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) 0000e 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_04KBFEPHFH@S?$IA?v4@ ; 6091 : { 00015 48 8b e9 mov rbp, rcx ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) 00018 48 8d 99 c0 00 00 00 lea rbx, QWORD PTR [rcx+192] 0001f e8 00 00 00 00 call stbi__pic_is4 00024 85 c0 test eax, eax 00026 75 08 jne SHORT $LN7@stbi__pic_ ; 5899 : return 0; 00028 45 33 ff xor r15d, r15d 0002b e9 b5 00 00 00 jmp $LN3@stbi__pic_ $LN7@stbi__pic_: 00030 48 89 7c 24 48 mov QWORD PTR [rsp+72], rdi ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) 00035 bf 54 00 00 00 mov edi, 84 ; 00000054H 0003a 4c 89 64 24 50 mov QWORD PTR [rsp+80], r12 0003f 48 89 74 24 40 mov QWORD PTR [rsp+64], rsi 00044 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL6@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00050 48 8b 03 mov rax, QWORD PTR [rbx] 00053 48 8d 75 30 lea rsi, QWORD PTR [rbp+48] 00057 48 3b 85 c8 00 00 00 cmp rax, QWORD PTR [rbp+200] 0005e 73 08 jae SHORT $LN11@stbi__pic_ ; 1078 : return *s->img_buffer++; 00060 48 ff c0 inc rax 00063 48 89 03 mov QWORD PTR [rbx], rax 00066 eb 13 jmp SHORT $LN4@stbi__pic_ $LN11@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 00068 83 3e 00 cmp DWORD PTR [rsi], 0 0006b 74 0e je SHORT $LN4@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 0006d 48 8b cd mov rcx, rbp 00070 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00075 48 ff 03 inc QWORD PTR [rbx] 00078 48 8b 03 mov rax, QWORD PTR [rbx] $LN4@stbi__pic_: ; 5901 : for (i = 0; i < 84; ++i) 0007b 48 83 ef 01 sub rdi, 1 0007f 75 cf jne SHORT $LL6@stbi__pic_ 00081 45 33 ff xor r15d, r15d 00084 4c 8d 25 00 00 00 00 lea r12, OFFSET FLAT:??_C@_04ELNJHLFH@PICT@ 0008b 41 8b ff mov edi, r15d 0008e 66 90 npad 2 $LL17@stbi__pic_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00090 48 3b 85 c8 00 00 00 cmp rax, QWORD PTR [rbp+200] 00097 73 0b jae SHORT $LN21@stbi__pic_ ; 1078 : return *s->img_buffer++; 00099 0f b6 08 movzx ecx, BYTE PTR [rax] 0009c 48 ff c0 inc rax 0009f 48 89 03 mov QWORD PTR [rbx], rax 000a2 eb 1d jmp SHORT $LN20@stbi__pic_ $LN21@stbi__pic_: ; 1079 : if (s->read_from_callbacks) { 000a4 44 39 3e cmp DWORD PTR [rsi], r15d 000a7 74 16 je SHORT $LN22@stbi__pic_ ; 1080 : stbi__refill_buffer(s); 000a9 48 8b cd mov rcx, rbp 000ac e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000b1 48 8b 03 mov rax, QWORD PTR [rbx] 000b4 0f b6 08 movzx ecx, BYTE PTR [rax] 000b7 48 ff c0 inc rax 000ba 48 89 03 mov QWORD PTR [rbx], rax 000bd eb 02 jmp SHORT $LN20@stbi__pic_ $LN22@stbi__pic_: ; 1082 : } ; 1083 : return 0; 000bf 32 c9 xor cl, cl $LN20@stbi__pic_: ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) 000c1 42 3a 0c 27 cmp cl, BYTE PTR [rdi+r12] 000c5 75 0f jne SHORT $LN36@stbi__pic_ ; 1084 : } ; 1085 : ; 1086 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1087 : // nothing ; 1088 : #else ; 1089 : stbi_inline static int stbi__at_eof(stbi__context* s) ; 1090 : { ; 1091 : if (s->io.read) { ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) 000c7 48 ff c7 inc rdi 000ca 48 83 ff 04 cmp rdi, 4 000ce 7c c0 jl SHORT $LL17@stbi__pic_ ; 5907 : return 1; 000d0 41 bf 01 00 00 00 mov r15d, 1 $LN36@stbi__pic_: 000d6 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 000db 48 8b 7c 24 48 mov rdi, QWORD PTR [rsp+72] 000e0 4c 8b 64 24 50 mov r12, QWORD PTR [rsp+80] $LN3@stbi__pic_: ; 342 : s->img_buffer = s->img_buffer_original; 000e5 48 8b 8d d0 00 00 00 mov rcx, QWORD PTR [rbp+208] ; 6092 : int r = stbi__pic_test_core(s); ; 6093 : stbi__rewind(s); ; 6094 : return r; 000ec 41 8b c7 mov eax, r15d ; 342 : s->img_buffer = s->img_buffer_original; 000ef 48 89 0b mov QWORD PTR [rbx], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 000f2 48 8b 8d d8 00 00 00 mov rcx, QWORD PTR [rbp+216] ; 6095 : } 000f9 48 8b 5c 24 58 mov rbx, QWORD PTR [rsp+88] ; 343 : s->img_buffer_end = s->img_buffer_original_end; 000fe 48 89 8d c8 00 00 00 mov QWORD PTR [rbp+200], rcx ; 6095 : } 00105 48 83 c4 20 add rsp, 32 ; 00000020H 00109 41 5f pop r15 0010b 41 5e pop r14 0010d 5d pop rbp 0010e c3 ret 0 stbi__pic_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_test_raw _TEXT SEGMENT s$ = 48 stbi__gif_test_raw PROC ; COMDAT ; 6130 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 6130 : { 00011 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 72 16 jb SHORT $LN52@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0001d 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00021 0f 84 3b 01 00 00 je $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00027 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0002c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN52@stbi__gif_: ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; 00033 0f b6 08 movzx ecx, BYTE PTR [rax] 00036 48 ff c0 inc rax 00039 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00040 80 f9 47 cmp cl, 71 ; 00000047H 00043 0f 85 19 01 00 00 jne $LN3@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00049 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00050 72 19 jb SHORT $LN53@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 00052 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00056 0f 84 06 01 00 00 je $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 0005c 48 8b cb mov rcx, rbx 0005f e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00064 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN53@stbi__gif_: ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; 0006b 0f b6 08 movzx ecx, BYTE PTR [rax] 0006e 48 ff c0 inc rax 00071 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00078 80 f9 49 cmp cl, 73 ; 00000049H 0007b 0f 85 e1 00 00 00 jne $LN3@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00081 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00088 72 19 jb SHORT $LN54@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0008a 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0008e 0f 84 ce 00 00 00 je $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00094 48 8b cb mov rcx, rbx 00097 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0009c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN54@stbi__gif_: ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; 000a3 0f b6 08 movzx ecx, BYTE PTR [rax] 000a6 48 ff c0 inc rax 000a9 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000b0 80 f9 46 cmp cl, 70 ; 00000046H 000b3 0f 85 a9 00 00 00 jne $LN3@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 000b9 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000c0 72 19 jb SHORT $LN55@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 000c2 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000c6 0f 84 96 00 00 00 je $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000cc 48 8b cb mov rcx, rbx 000cf e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000d4 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN55@stbi__gif_: ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; 000db 0f b6 08 movzx ecx, BYTE PTR [rax] 000de 48 ff c0 inc rax 000e1 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000e8 80 f9 38 cmp cl, 56 ; 00000038H 000eb 75 75 jne SHORT $LN3@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 000ed 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000f4 72 15 jb SHORT $LN56@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 000f6 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000fa 74 66 je SHORT $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000fc 48 8b cb mov rcx, rbx 000ff e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00104 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN56@stbi__gif_: ; 6133 : sz = stbi__get8(s); ; 6134 : if (sz != '9' && sz != '7') return 0; 0010b 0f b6 08 movzx ecx, BYTE PTR [rax] 0010e 48 ff c0 inc rax 00111 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00118 80 f9 39 cmp cl, 57 ; 00000039H 0011b 74 05 je SHORT $LN4@stbi__gif_ 0011d 80 f9 37 cmp cl, 55 ; 00000037H 00120 75 40 jne SHORT $LN3@stbi__gif_ $LN4@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00122 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00129 72 15 jb SHORT $LN57@stbi__gif_ ; 1078 : return *s->img_buffer++; ; 1079 : if (s->read_from_callbacks) { 0012b 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0012f 74 31 je SHORT $LN3@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00131 48 8b cb mov rcx, rbx 00134 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00139 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN57@stbi__gif_: ; 6135 : if (stbi__get8(s) != 'a') return 0; 00140 0f b6 08 movzx ecx, BYTE PTR [rax] 00143 48 ff c0 inc rax 00146 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0014d 80 f9 61 cmp cl, 97 ; 00000061H 00150 75 10 jne SHORT $LN3@stbi__gif_ ; 6136 : return 1; 00152 b8 01 00 00 00 mov eax, 1 ; 6137 : } 00157 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0015c 48 83 c4 20 add rsp, 32 ; 00000020H 00160 5f pop rdi 00161 c3 ret 0 $LN3@stbi__gif_: 00162 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00167 33 c0 xor eax, eax 00169 48 83 c4 20 add rsp, 32 ; 00000020H 0016d 5f pop rdi 0016e c3 ret 0 stbi__gif_test_raw ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_test _TEXT SEGMENT s$ = 48 stbi__gif_test PROC ; COMDAT ; 6140 : { 00000 40 53 push rbx 00002 48 83 ec 20 sub rsp, 32 ; 00000020H 00006 48 8b d9 mov rbx, rcx ; 6141 : int r = stbi__gif_test_raw(s); 00009 e8 00 00 00 00 call stbi__gif_test_raw ; 342 : s->img_buffer = s->img_buffer_original; 0000e 48 8b 93 d0 00 00 00 mov rdx, QWORD PTR [rbx+208] 00015 48 89 93 c0 00 00 00 mov QWORD PTR [rbx+192], rdx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0001c 48 8b 93 d8 00 00 00 mov rdx, QWORD PTR [rbx+216] 00023 48 89 93 c8 00 00 00 mov QWORD PTR [rbx+200], rdx ; 6142 : stbi__rewind(s); ; 6143 : return r; ; 6144 : } 0002a 48 83 c4 20 add rsp, 32 ; 00000020H 0002e 5b pop rbx 0002f c3 ret 0 stbi__gif_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_parse_colortable _TEXT SEGMENT s$ = 64 pal$ = 72 num_entries$ = 80 transp$ = 88 stbi__gif_parse_colortable PROC ; COMDAT ; 6148 : int i; ; 6149 : for (i = 0; i < num_entries; ++i) { 00000 45 85 c0 test r8d, r8d 00003 0f 8e 45 01 00 00 jle $LN29@stbi__gif_ 00009 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 0000e 48 89 6c 24 18 mov QWORD PTR [rsp+24], rbp 00013 56 push rsi 00014 41 56 push r14 00016 41 57 push r15 00018 48 83 ec 20 sub rsp, 32 ; 00000020H 0001c 45 33 ff xor r15d, r15d 0001f 48 89 7c 24 40 mov QWORD PTR [rsp+64], rdi 00024 41 8b f7 mov esi, r15d 00027 49 63 e8 movsxd rbp, r8d 0002a 45 8b f1 mov r14d, r9d 0002d 48 8d 7a 01 lea rdi, QWORD PTR [rdx+1] 00031 48 8b d9 mov rbx, rcx 00034 0f 1f 40 00 0f 1f 84 00 00 00 00 00 npad 12 $LL4@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00040 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00047 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0004e 73 0f jae SHORT $LN7@stbi__gif_ ; 1078 : return *s->img_buffer++; 00050 0f b6 08 movzx ecx, BYTE PTR [rax] 00053 48 ff c0 inc rax 00056 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0005d eb 26 jmp SHORT $LN6@stbi__gif_ $LN7@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 0005f 44 39 7b 30 cmp DWORD PTR [rbx+48], r15d 00063 74 1e je SHORT $LN8@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00065 48 8b cb mov rcx, rbx 00068 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0006d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00074 0f b6 08 movzx ecx, BYTE PTR [rax] 00077 48 ff c0 inc rax 0007a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00081 eb 02 jmp SHORT $LN6@stbi__gif_ $LN8@stbi__gif_: ; 1082 : } ; 1083 : return 0; 00083 32 c9 xor cl, cl $LN6@stbi__gif_: ; 6150 : pal[i][2] = stbi__get8(s); 00085 88 4f 01 mov BYTE PTR [rdi+1], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00088 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0008f 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00096 73 0f jae SHORT $LN11@stbi__gif_ ; 1078 : return *s->img_buffer++; 00098 0f b6 08 movzx ecx, BYTE PTR [rax] 0009b 48 ff c0 inc rax 0009e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000a5 eb 26 jmp SHORT $LN10@stbi__gif_ $LN11@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 000a7 44 39 7b 30 cmp DWORD PTR [rbx+48], r15d 000ab 74 1e je SHORT $LN12@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000ad 48 8b cb mov rcx, rbx 000b0 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000b5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000bc 0f b6 08 movzx ecx, BYTE PTR [rax] 000bf 48 ff c0 inc rax 000c2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000c9 eb 02 jmp SHORT $LN10@stbi__gif_ $LN12@stbi__gif_: ; 1082 : } ; 1083 : return 0; 000cb 32 c9 xor cl, cl $LN10@stbi__gif_: ; 6151 : pal[i][1] = stbi__get8(s); 000cd 88 0f mov BYTE PTR [rdi], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 000cf 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000d6 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000dd 73 0f jae SHORT $LN15@stbi__gif_ ; 1078 : return *s->img_buffer++; 000df 0f b6 08 movzx ecx, BYTE PTR [rax] 000e2 48 ff c0 inc rax 000e5 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000ec eb 26 jmp SHORT $LN14@stbi__gif_ $LN15@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 000ee 44 39 7b 30 cmp DWORD PTR [rbx+48], r15d 000f2 74 1e je SHORT $LN16@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000f4 48 8b cb mov rcx, rbx 000f7 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000fc 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00103 0f b6 08 movzx ecx, BYTE PTR [rax] 00106 48 ff c0 inc rax 00109 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00110 eb 02 jmp SHORT $LN14@stbi__gif_ $LN16@stbi__gif_: ; 1082 : } ; 1083 : return 0; 00112 32 c9 xor cl, cl $LN14@stbi__gif_: ; 6152 : pal[i][0] = stbi__get8(s); ; 6153 : pal[i][3] = transp == i ? 0 : 255; 00114 44 3b f6 cmp r14d, esi 00117 88 4f ff mov BYTE PTR [rdi-1], cl 0011a b8 ff 00 00 00 mov eax, 255 ; 000000ffH 0011f 41 0f 44 c7 cmove eax, r15d 00123 ff c6 inc esi 00125 88 47 02 mov BYTE PTR [rdi+2], al 00128 48 83 c7 04 add rdi, 4 0012c 48 83 ed 01 sub rbp, 1 00130 0f 85 0a ff ff ff jne $LL4@stbi__gif_ ; 6154 : } ; 6155 : } 00136 48 8b 7c 24 40 mov rdi, QWORD PTR [rsp+64] 0013b 48 8b 5c 24 48 mov rbx, QWORD PTR [rsp+72] 00140 48 8b 6c 24 50 mov rbp, QWORD PTR [rsp+80] 00145 48 83 c4 20 add rsp, 32 ; 00000020H 00149 41 5f pop r15 0014b 41 5e pop r14 0014d 5e pop rsi $LN29@stbi__gif_: 0014e c3 ret 0 stbi__gif_parse_colortable ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_header _TEXT SEGMENT s$ = 48 g$ = 56 comp$ = 64 is_info$dead$ = 72 stbi__gif_header PROC ; COMDAT ; 6158 : { 00000 48 89 5c 24 10 mov QWORD PTR [rsp+16], rbx 00005 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000a 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 0000f 41 57 push r15 00011 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 00015 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 6158 : { 0001c 4d 8b f8 mov r15, r8 0001f 48 8b f2 mov rsi, rdx 00022 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00025 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0002c 72 16 jb SHORT $LN92@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 0002e 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00032 0f 84 ff 02 00 00 je $LN60@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00038 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0003d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN92@stbi__gif_: ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') 00044 0f b6 08 movzx ecx, BYTE PTR [rax] 00047 48 ff c0 inc rax 0004a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00051 80 f9 47 cmp cl, 71 ; 00000047H 00054 0f 85 dd 02 00 00 jne $LN60@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0005a 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00061 72 19 jb SHORT $LN93@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 00063 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00067 0f 84 ca 02 00 00 je $LN60@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 0006d 48 8b cb mov rcx, rbx 00070 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00075 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN93@stbi__gif_: ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') 0007c 0f b6 08 movzx ecx, BYTE PTR [rax] 0007f 48 ff c0 inc rax 00082 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00089 80 f9 49 cmp cl, 73 ; 00000049H 0008c 0f 85 a5 02 00 00 jne $LN60@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00092 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00099 72 19 jb SHORT $LN94@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 0009b 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0009f 0f 84 92 02 00 00 je $LN60@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000a5 48 8b cb mov rcx, rbx 000a8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000ad 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN94@stbi__gif_: ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') 000b4 0f b6 08 movzx ecx, BYTE PTR [rax] 000b7 48 ff c0 inc rax 000ba 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000c1 80 f9 46 cmp cl, 70 ; 00000046H 000c4 0f 85 6d 02 00 00 jne $LN60@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 000ca 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000d1 72 19 jb SHORT $LN95@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 000d3 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000d7 0f 84 5a 02 00 00 je $LN60@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 000dd 48 8b cb mov rcx, rbx 000e0 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000e5 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN95@stbi__gif_: ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') 000ec 0f b6 08 movzx ecx, BYTE PTR [rax] 000ef 48 ff c0 inc rax 000f2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000f9 80 f9 38 cmp cl, 56 ; 00000038H 000fc 0f 85 35 02 00 00 jne $LN60@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00102 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00109 72 19 jb SHORT $LN96@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 0010b 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0010f 0f 84 22 02 00 00 je $LN60@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00115 48 8b cb mov rcx, rbx 00118 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0011d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN96@stbi__gif_: ; 6161 : return stbi__err("not GIF", "Corrupt GIF"); ; 6162 : ; 6163 : version = stbi__get8(s); ; 6164 : if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); 00124 0f b6 08 movzx ecx, BYTE PTR [rax] 00127 48 ff c0 inc rax 0012a 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00131 80 f9 37 cmp cl, 55 ; 00000037H 00134 74 09 je SHORT $LN4@stbi__gif_ 00136 80 f9 39 cmp cl, 57 ; 00000039H 00139 0f 85 f8 01 00 00 jne $LN60@stbi__gif_ $LN4@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0013f 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00146 72 19 jb SHORT $LN97@stbi__gif_ ; 1079 : if (s->read_from_callbacks) { 00148 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0014c 0f 84 bd 01 00 00 je $LN36@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00152 48 8b cb mov rcx, rbx 00155 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0015a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN97@stbi__gif_: ; 6165 : if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); 00161 0f b6 10 movzx edx, BYTE PTR [rax] 00164 48 ff c0 inc rax 00167 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0016e 41 b9 00 00 00 00 mov r9d, OFFSET FLAT:stbi__g_failure_reason 00174 80 fa 61 cmp dl, 97 ; 00000061H 00177 0f 85 98 01 00 00 jne $LN58@stbi__gif_ ; 6166 : ; 6167 : stbi__g_failure_reason = ""; 0017d 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00183 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0018c 4c 89 74 24 30 mov QWORD PTR [rsp+48], r14 00191 4c 8b 34 c8 mov r14, QWORD PTR [rax+rcx*8] 00195 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_00CNPNBAHC@@ 0019c 4d 03 f1 add r14, r9 ; 6168 : g->w = stbi__get16le(s); 0019f 48 8b cb mov rcx, rbx 001a2 49 89 06 mov QWORD PTR [r14], rax 001a5 e8 00 00 00 00 call stbi__get16le ; 6169 : g->h = stbi__get16le(s); 001aa 48 8b cb mov rcx, rbx 001ad 89 06 mov DWORD PTR [rsi], eax 001af e8 00 00 00 00 call stbi__get16le 001b4 89 46 04 mov DWORD PTR [rsi+4], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 001b7 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001be 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 001c5 73 0f jae SHORT $LN41@stbi__gif_ ; 1078 : return *s->img_buffer++; 001c7 0f b6 08 movzx ecx, BYTE PTR [rax] 001ca 48 ff c0 inc rax 001cd 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001d4 eb 26 jmp SHORT $LN40@stbi__gif_ $LN41@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 001d6 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 001da 74 1e je SHORT $LN42@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 001dc 48 8b cb mov rcx, rbx 001df e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001e4 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001eb 0f b6 08 movzx ecx, BYTE PTR [rax] 001ee 48 ff c0 inc rax 001f1 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001f8 eb 02 jmp SHORT $LN40@stbi__gif_ $LN42@stbi__gif_: ; 1082 : } ; 1083 : return 0; 001fa 32 c9 xor cl, cl $LN40@stbi__gif_: ; 6170 : g->flags = stbi__get8(s); 001fc 0f b6 c1 movzx eax, cl 001ff 89 46 20 mov DWORD PTR [rsi+32], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 00202 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00209 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00210 73 0f jae SHORT $LN45@stbi__gif_ ; 1078 : return *s->img_buffer++; 00212 0f b6 08 movzx ecx, BYTE PTR [rax] 00215 48 ff c0 inc rax 00218 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0021f eb 26 jmp SHORT $LN44@stbi__gif_ $LN45@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 00221 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00225 74 1e je SHORT $LN46@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00227 48 8b cb mov rcx, rbx 0022a e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0022f 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00236 0f b6 08 movzx ecx, BYTE PTR [rax] 00239 48 ff c0 inc rax 0023c 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00243 eb 02 jmp SHORT $LN44@stbi__gif_ $LN46@stbi__gif_: ; 1082 : } ; 1083 : return 0; 00245 32 c9 xor cl, cl $LN44@stbi__gif_: ; 6171 : g->bgindex = stbi__get8(s); 00247 0f b6 c1 movzx eax, cl 0024a 89 46 24 mov DWORD PTR [rsi+36], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 0024d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00254 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0025b 73 0f jae SHORT $LN49@stbi__gif_ ; 1078 : return *s->img_buffer++; 0025d 0f b6 08 movzx ecx, BYTE PTR [rax] 00260 48 ff c0 inc rax 00263 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0026a eb 26 jmp SHORT $LN48@stbi__gif_ $LN49@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 0026c 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00270 74 1e je SHORT $LN50@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00272 48 8b cb mov rcx, rbx 00275 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0027a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00281 0f b6 08 movzx ecx, BYTE PTR [rax] 00284 48 ff c0 inc rax 00287 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0028e eb 02 jmp SHORT $LN48@stbi__gif_ $LN50@stbi__gif_: ; 1082 : } ; 1083 : return 0; 00290 32 c9 xor cl, cl $LN48@stbi__gif_: ; 6172 : g->ratio = stbi__get8(s); ; 6173 : g->transparent = -1; ; 6174 : ; 6175 : if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 00292 81 3e 00 00 00 01 cmp DWORD PTR [rsi], 16777216 ; 01000000H 00298 0f b6 c1 movzx eax, cl 0029b 89 46 28 mov DWORD PTR [rsi+40], eax 0029e c7 46 2c ff ff ff ff mov DWORD PTR [rsi+44], -1 002a5 7f 5a jg SHORT $LN61@stbi__gif_ ; 6176 : if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 002a7 81 7e 04 00 00 00 01 cmp DWORD PTR [rsi+4], 16777216 ; 01000000H 002ae 7f 51 jg SHORT $LN61@stbi__gif_ ; 6177 : ; 6178 : if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments 002b0 4d 85 ff test r15, r15 002b3 74 07 je SHORT $LN8@stbi__gif_ 002b5 41 c7 07 04 00 00 00 mov DWORD PTR [r15], 4 $LN8@stbi__gif_: ; 6179 : ; 6180 : if (is_info) return 1; ; 6181 : ; 6182 : if (g->flags & 0x80) 002bc 8b 4e 20 mov ecx, DWORD PTR [rsi+32] 002bf 84 c9 test cl, cl 002c1 79 1e jns SHORT $LN10@stbi__gif_ ; 6183 : stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); 002c3 83 e1 07 and ecx, 7 002c6 48 8d 56 34 lea rdx, QWORD PTR [rsi+52] 002ca 41 b8 02 00 00 00 mov r8d, 2 002d0 41 b9 ff ff ff ff mov r9d, -1 002d6 41 d3 e0 shl r8d, cl 002d9 48 8b cb mov rcx, rbx 002dc e8 00 00 00 00 call stbi__gif_parse_colortable $LN10@stbi__gif_: ; 6184 : ; 6185 : return 1; 002e1 b8 01 00 00 00 mov eax, 1 $LN91@stbi__gif_: 002e6 4c 8b 74 24 30 mov r14, QWORD PTR [rsp+48] $LN1@stbi__gif_: ; 6186 : } 002eb 48 8b 5c 24 38 mov rbx, QWORD PTR [rsp+56] 002f0 48 8b 74 24 40 mov rsi, QWORD PTR [rsp+64] 002f5 48 8b 7c 24 48 mov rdi, QWORD PTR [rsp+72] 002fa 48 83 c4 20 add rsp, 32 ; 00000020H 002fe 41 5f pop r15 00300 c3 ret 0 $LN61@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 00301 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 00308 49 89 06 mov QWORD PTR [r14], rax ; 6176 : if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); 0030b 33 c0 xor eax, eax 0030d eb d7 jmp SHORT $LN91@stbi__gif_ $LN36@stbi__gif_: ; 1083 : return 0; 0030f 41 b9 00 00 00 00 mov r9d, OFFSET FLAT:stbi__g_failure_reason $LN58@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 00315 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0031e 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:??_C@_07KMJLPAII@not?5GIF@ 00325 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 0032b 48 8b 14 c8 mov rdx, QWORD PTR [rax+rcx*8] ; 6165 : if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); 0032f 33 c0 xor eax, eax ; 431 : stbi__g_failure_reason = str; 00331 4d 89 04 11 mov QWORD PTR [r9+rdx], r8 ; 6165 : if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); 00335 eb b4 jmp SHORT $LN1@stbi__gif_ $LN60@stbi__gif_: ; 6186 : } 00337 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0033d 4c 8d 05 00 00 00 00 lea r8, OFFSET FLAT:??_C@_07KMJLPAII@not?5GIF@ 00344 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0034d b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00352 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00356 4c 89 04 01 mov QWORD PTR [rcx+rax], r8 0035a 33 c0 xor eax, eax 0035c eb 8d jmp SHORT $LN1@stbi__gif_ stbi__gif_header ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__out_gif_code _TEXT SEGMENT g$ = 48 code$ = 56 stbi__out_gif_code PROC ; COMDAT ; 6204 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 6205 : stbi_uc* p, * c; ; 6206 : int idx; ; 6207 : ; 6208 : // recurse to decode the prefixes, since the linked-list is backwards, ; 6209 : // and working backwards through an interleaved image would be nasty ; 6210 : if (g->codes[code].prefix >= 0) 0000a 0f b7 fa movzx edi, dx 0000d 48 8b d9 mov rbx, rcx 00010 0f b7 94 b9 34 08 00 00 movzx edx, WORD PTR [rcx+rdi*4+2100] 00018 66 85 d2 test dx, dx 0001b 78 05 js SHORT $LN4@stbi__out_ ; 6211 : stbi__out_gif_code(g, g->codes[code].prefix); 0001d e8 00 00 00 00 call stbi__out_gif_code $LN4@stbi__out_: ; 6212 : ; 6213 : if (g->cur_y >= g->max_y) return; 00022 8b 8b 60 88 00 00 mov ecx, DWORD PTR [rbx+34912] 00028 3b 8b 58 88 00 00 cmp ecx, DWORD PTR [rbx+34904] 0002e 0f 8d d8 00 00 00 jge $LN13@stbi__out_ ; 6214 : ; 6215 : idx = g->cur_x + g->cur_y; 00034 8b 83 5c 88 00 00 mov eax, DWORD PTR [rbx+34908] 0003a 03 c1 add eax, ecx ; 6216 : p = &g->out[idx]; 0003c 4c 63 c0 movsxd r8, eax ; 6217 : g->history[idx / 4] = 1; 0003f 99 cdq 00040 4c 03 43 08 add r8, QWORD PTR [rbx+8] 00044 83 e2 03 and edx, 3 00047 03 c2 add eax, edx 00049 c1 f8 02 sar eax, 2 0004c 48 63 c8 movsxd rcx, eax 0004f 48 8b 43 18 mov rax, QWORD PTR [rbx+24] 00053 c6 04 01 01 mov BYTE PTR [rcx+rax], 1 ; 6218 : ; 6219 : c = &g->color_table[g->codes[code].suffix * 4]; 00057 0f b6 8c bb 37 08 00 00 movzx ecx, BYTE PTR [rbx+rdi*4+2103] 0005f 48 8b 83 38 88 00 00 mov rax, QWORD PTR [rbx+34872] ; 6220 : if (c[3] > 128) { // don't render transparent pixels; 00066 80 7c 88 03 80 cmp BYTE PTR [rax+rcx*4+3], 128 ; 00000080H 0006b 48 8d 14 88 lea rdx, QWORD PTR [rax+rcx*4] 0006f 76 1e jbe SHORT $LN6@stbi__out_ ; 6221 : p[0] = c[2]; 00071 0f b6 42 02 movzx eax, BYTE PTR [rdx+2] 00075 41 88 00 mov BYTE PTR [r8], al ; 6222 : p[1] = c[1]; 00078 0f b6 42 01 movzx eax, BYTE PTR [rdx+1] 0007c 41 88 40 01 mov BYTE PTR [r8+1], al ; 6223 : p[2] = c[0]; 00080 0f b6 02 movzx eax, BYTE PTR [rdx] 00083 41 88 40 02 mov BYTE PTR [r8+2], al ; 6224 : p[3] = c[3]; 00087 0f b6 42 03 movzx eax, BYTE PTR [rdx+3] 0008b 41 88 40 03 mov BYTE PTR [r8+3], al $LN6@stbi__out_: ; 6225 : } ; 6226 : g->cur_x += 4; 0008f 83 83 5c 88 00 00 04 add DWORD PTR [rbx+34908], 4 00096 8b 83 5c 88 00 00 mov eax, DWORD PTR [rbx+34908] ; 6227 : ; 6228 : if (g->cur_x >= g->max_x) { 0009c 3b 83 54 88 00 00 cmp eax, DWORD PTR [rbx+34900] 000a2 7c 68 jl SHORT $LN13@stbi__out_ ; 6229 : g->cur_x = g->start_x; 000a4 8b 83 4c 88 00 00 mov eax, DWORD PTR [rbx+34892] ; 6230 : g->cur_y += g->step; ; 6231 : ; 6232 : while (g->cur_y >= g->max_y && g->parse > 0) { 000aa 44 8b 8b 58 88 00 00 mov r9d, DWORD PTR [rbx+34904] 000b1 89 83 5c 88 00 00 mov DWORD PTR [rbx+34908], eax 000b7 8b 83 44 88 00 00 mov eax, DWORD PTR [rbx+34884] 000bd 01 83 60 88 00 00 add DWORD PTR [rbx+34912], eax 000c3 44 39 8b 60 88 00 00 cmp DWORD PTR [rbx+34912], r9d 000ca 7c 40 jl SHORT $LN13@stbi__out_ 000cc 0f 1f 40 00 npad 4 $LL2@stbi__out_: 000d0 44 8b 83 40 88 00 00 mov r8d, DWORD PTR [rbx+34880] 000d7 45 85 c0 test r8d, r8d 000da 7e 30 jle SHORT $LN13@stbi__out_ ; 6233 : g->step = (1 << g->parse) * g->line_size; 000dc 8b 93 64 88 00 00 mov edx, DWORD PTR [rbx+34916] ; 6234 : g->cur_y = g->start_y + (g->step >> 1); ; 6235 : --g->parse; 000e2 41 8d 40 ff lea eax, DWORD PTR [r8-1] 000e6 41 8b c8 mov ecx, r8d 000e9 89 83 40 88 00 00 mov DWORD PTR [rbx+34880], eax 000ef d3 e2 shl edx, cl 000f1 8b 8b 50 88 00 00 mov ecx, DWORD PTR [rbx+34896] 000f7 89 93 44 88 00 00 mov DWORD PTR [rbx+34884], edx 000fd d1 fa sar edx, 1 000ff 03 ca add ecx, edx 00101 89 8b 60 88 00 00 mov DWORD PTR [rbx+34912], ecx 00107 41 3b c9 cmp ecx, r9d 0010a 7d c4 jge SHORT $LL2@stbi__out_ $LN13@stbi__out_: ; 6236 : } ; 6237 : } ; 6238 : } 0010c 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00111 48 83 c4 20 add rsp, 32 ; 00000020H 00115 5f pop rdi 00116 c3 ret 0 stbi__out_gif_code ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__process_gif_raster _TEXT SEGMENT tv922 = 32 tv925 = 36 $T4 = 40 bits$1$ = 112 s$ = 112 g$ = 120 first$1$ = 128 clear$1$ = 136 stbi__process_gif_raster PROC ; COMDAT ; 6241 : { 00000 40 53 push rbx 00002 41 55 push r13 00004 48 83 ec 58 sub rsp, 88 ; 00000058H ; 1077 : if (s->img_buffer < s->img_buffer_end) 00008 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 6241 : { 0000f 4c 8b ea mov r13, rdx 00012 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00015 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001c 72 12 jb SHORT $LN123@stbi__proc ; 1079 : if (s->read_from_callbacks) { 0001e 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00022 74 28 je SHORT $LN32@stbi__proc ; 1080 : stbi__refill_buffer(s); 00024 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00029 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN123@stbi__proc: ; 6242 : stbi_uc lzw_cs; ; 6243 : stbi__int32 len, init_code; ; 6244 : stbi__uint32 first; ; 6245 : stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; ; 6246 : stbi__gif_lzw* p; ; 6247 : ; 6248 : lzw_cs = stbi__get8(s); ; 6249 : if (lzw_cs > 12) return NULL; 00030 0f b6 08 movzx ecx, BYTE PTR [rax] 00033 48 ff c0 inc rax 00036 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0003d 80 f9 0c cmp cl, 12 00040 76 0c jbe SHORT $LN86@stbi__proc 00042 33 c0 xor eax, eax ; 6328 : } 00044 48 83 c4 58 add rsp, 88 ; 00000058H 00048 41 5d pop r13 0004a 5b pop rbx 0004b c3 ret 0 $LN32@stbi__proc: ; 1083 : return 0; 0004c 32 c9 xor cl, cl $LN86@stbi__proc: 0004e 48 89 6c 24 78 mov QWORD PTR [rsp+120], rbp ; 6251 : first = 1; 00053 41 bb 01 00 00 00 mov r11d, 1 00059 0f b6 c9 movzx ecx, cl ; 6252 : codesize = lzw_cs + 1; ; 6253 : codemask = (1 << codesize) - 1; ; 6254 : bits = 0; 0005c 45 33 c9 xor r9d, r9d 0005f 48 89 74 24 50 mov QWORD PTR [rsp+80], rsi 00064 ba 01 00 00 00 mov edx, 1 00069 d3 e2 shl edx, cl 0006b 41 8b eb mov ebp, r11d 0006e 48 89 7c 24 48 mov QWORD PTR [rsp+72], rdi ; 6255 : valid_bits = 0; ; 6256 : for (init_code = 0; init_code < clear; init_code++) { 00073 45 8d 43 fe lea r8d, QWORD PTR [r11-2] 00077 8d 41 01 lea eax, DWORD PTR [rcx+1] 0007a 4c 89 64 24 40 mov QWORD PTR [rsp+64], r12 0007f 8b c8 mov ecx, eax 00081 4c 89 74 24 38 mov QWORD PTR [rsp+56], r14 00086 d3 e5 shl ebp, cl 00088 45 33 e4 xor r12d, r12d 0008b ff cd dec ebp 0008d 4c 89 7c 24 30 mov QWORD PTR [rsp+48], r15 00092 33 c9 xor ecx, ecx 00094 89 94 24 88 00 00 00 mov DWORD PTR clear$1$[rsp], edx 0009b 44 89 9c 24 80 00 00 00 mov DWORD PTR first$1$[rsp], r11d 000a3 44 8b f8 mov r15d, eax 000a6 89 44 24 24 mov DWORD PTR tv925[rsp], eax 000aa 44 89 4c 24 70 mov DWORD PTR bits$1$[rsp], r9d 000af 85 d2 test edx, edx 000b1 7e 21 jle SHORT $LN3@stbi__proc ; 6250 : clear = 1 << lzw_cs; 000b3 49 8d 85 36 08 00 00 lea rax, QWORD PTR [r13+2102] 000ba 66 0f 1f 44 00 00 npad 6 $LL4@stbi__proc: ; 6257 : g->codes[init_code].prefix = -1; ; 6258 : g->codes[init_code].first = (stbi_uc)init_code; 000c0 88 08 mov BYTE PTR [rax], cl ; 6259 : g->codes[init_code].suffix = (stbi_uc)init_code; 000c2 88 48 01 mov BYTE PTR [rax+1], cl 000c5 ff c1 inc ecx 000c7 66 44 89 40 fe mov WORD PTR [rax-2], r8w 000cc 48 8d 40 04 lea rax, QWORD PTR [rax+4] 000d0 3b ca cmp ecx, edx 000d2 7c ec jl SHORT $LL4@stbi__proc $LN3@stbi__proc: ; 6260 : } ; 6261 : ; 6262 : // support no starting clear code ; 6263 : avail = clear + 2; 000d4 8d 42 02 lea eax, DWORD PTR [rdx+2] ; 6264 : oldcode = -1; 000d7 45 8b f0 mov r14d, r8d 000da 48 63 f0 movsxd rsi, eax ; 6265 : ; 6266 : len = 0; 000dd 33 ff xor edi, edi 000df 4c 8b c6 mov r8, rsi 000e2 48 89 74 24 28 mov QWORD PTR $T4[rsp], rsi 000e7 89 44 24 20 mov DWORD PTR tv922[rsp], eax 000eb 0f 1f 44 00 00 npad 5 $LL5@stbi__proc: ; 6267 : for (;;) { ; 6268 : if (valid_bits < codesize) { 000f0 45 3b e7 cmp r12d, r15d 000f3 0f 8d 10 01 00 00 jge $LN11@stbi__proc ; 6269 : if (len == 0) { 000f9 85 ff test edi, edi 000fb 0f 85 87 00 00 00 jne $LN87@stbi__proc ; 1077 : if (s->img_buffer < s->img_buffer_end) 00101 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00108 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0010f 73 0f jae SHORT $LN35@stbi__proc ; 1078 : return *s->img_buffer++; 00111 0f b6 08 movzx ecx, BYTE PTR [rax] 00114 48 ff c0 inc rax 00117 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0011e eb 2b jmp SHORT $LN124@stbi__proc $LN35@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 00120 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00124 74 23 je SHORT $LN36@stbi__proc ; 1080 : stbi__refill_buffer(s); 00126 48 8b cb mov rcx, rbx 00129 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0012e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00135 44 8b 4c 24 70 mov r9d, DWORD PTR bits$1$[rsp] 0013a 0f b6 08 movzx ecx, BYTE PTR [rax] 0013d 48 ff c0 inc rax 00140 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00147 eb 02 jmp SHORT $LN124@stbi__proc $LN36@stbi__proc: ; 1082 : } ; 1083 : return 0; 00149 32 c9 xor cl, cl $LN124@stbi__proc: ; 6270 : len = stbi__get8(s); // start new block 0014b 0f b6 f9 movzx edi, cl 0014e ba 30 00 00 00 mov edx, 48 ; 00000030H 00153 48 8b c3 mov rax, rbx 00156 4c 8d 04 1a lea r8, QWORD PTR [rdx+rbx] ; 6271 : if (len == 0) 0015a 84 c9 test cl, cl 0015c 75 2e jne SHORT $LN80@stbi__proc $LN9@stbi__proc: ; 6294 : return g->out; 0015e 49 8b 45 08 mov rax, QWORD PTR [r13+8] $LN122@stbi__proc: 00162 4c 8b 74 24 38 mov r14, QWORD PTR [rsp+56] 00167 4c 8b 64 24 40 mov r12, QWORD PTR [rsp+64] 0016c 48 8b 7c 24 48 mov rdi, QWORD PTR [rsp+72] 00171 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 00176 48 8b 6c 24 78 mov rbp, QWORD PTR [rsp+120] 0017b 4c 8b 7c 24 30 mov r15, QWORD PTR [rsp+48] ; 6328 : } 00180 48 83 c4 58 add rsp, 88 ; 00000058H 00184 41 5d pop r13 00186 5b pop rbx 00187 c3 ret 0 $LN87@stbi__proc: ; 6271 : if (len == 0) 00188 4c 8d 43 30 lea r8, QWORD PTR [rbx+48] $LN80@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0018c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] ; 6272 : return g->out; ; 6273 : } ; 6274 : --len; 00193 ff cf dec edi ; 1077 : if (s->img_buffer < s->img_buffer_end) 00195 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0019c 73 0f jae SHORT $LN39@stbi__proc ; 1078 : return *s->img_buffer++; 0019e 0f b6 08 movzx ecx, BYTE PTR [rax] 001a1 48 ff c0 inc rax 001a4 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001ab eb 2b jmp SHORT $LN38@stbi__proc $LN39@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 001ad 41 83 38 00 cmp DWORD PTR [r8], 0 001b1 74 23 je SHORT $LN40@stbi__proc ; 1080 : stbi__refill_buffer(s); 001b3 48 8b cb mov rcx, rbx 001b6 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 001bb 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001c2 44 8b 4c 24 70 mov r9d, DWORD PTR bits$1$[rsp] 001c7 0f b6 08 movzx ecx, BYTE PTR [rax] 001ca 48 ff c0 inc rax 001cd 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001d4 eb 02 jmp SHORT $LN38@stbi__proc $LN40@stbi__proc: ; 1082 : } ; 1083 : return 0; 001d6 32 c9 xor cl, cl $LN38@stbi__proc: ; 6275 : bits |= (stbi__int32)stbi__get8(s) << valid_bits; ; 6276 : valid_bits += 8; ; 6277 : } 001d8 8b 94 24 88 00 00 00 mov edx, DWORD PTR clear$1$[rsp] 001df 4c 8b 44 24 28 mov r8, QWORD PTR $T4[rsp] 001e4 44 8b 9c 24 80 00 00 00 mov r11d, DWORD PTR first$1$[rsp] 001ec 0f b6 c1 movzx eax, cl 001ef 41 8b cc mov ecx, r12d 001f2 d3 e0 shl eax, cl 001f4 44 0b c8 or r9d, eax 001f7 8b 44 24 20 mov eax, DWORD PTR tv922[rsp] 001fb 44 89 4c 24 70 mov DWORD PTR bits$1$[rsp], r9d 00200 41 83 c4 08 add r12d, 8 00204 e9 e7 fe ff ff jmp $LL5@stbi__proc $LN11@stbi__proc: ; 6278 : else { ; 6279 : stbi__int32 code = bits & codemask; 00209 45 8b d1 mov r10d, r9d ; 6280 : bits >>= codesize; 0020c 41 8b cf mov ecx, r15d 0020f 41 d3 f9 sar r9d, cl 00212 44 23 d5 and r10d, ebp ; 6281 : valid_bits -= codesize; 00215 45 2b e7 sub r12d, r15d 00218 44 89 4c 24 70 mov DWORD PTR bits$1$[rsp], r9d ; 6282 : // @OPTIMIZE: is there some way we can accelerate the non-clear path? ; 6283 : if (code == clear) { // clear code 0021d 44 3b d2 cmp r10d, edx 00220 75 35 jne SHORT $LN15@stbi__proc ; 6284 : codesize = lzw_cs + 1; 00222 44 8b 7c 24 24 mov r15d, DWORD PTR tv925[rsp] ; 6285 : codemask = (1 << codesize) - 1; 00227 bd 01 00 00 00 mov ebp, 1 0022c 41 8b cf mov ecx, r15d ; 6286 : avail = clear + 2; 0022f 4c 63 c2 movsxd r8, edx 00232 d3 e5 shl ebp, cl 00234 49 83 c0 02 add r8, 2 00238 ff cd dec ebp 0023a 4c 89 44 24 28 mov QWORD PTR $T4[rsp], r8 ; 6287 : oldcode = -1; ; 6288 : first = 0; 0023f 45 33 db xor r11d, r11d 00242 8b f0 mov esi, eax 00244 44 89 9c 24 80 00 00 00 mov DWORD PTR first$1$[rsp], r11d 0024c 41 be ff ff ff ff mov r14d, -1 ; 6289 : } 00252 e9 99 fe ff ff jmp $LL5@stbi__proc $LN15@stbi__proc: ; 6290 : else if (code == clear + 1) { // end of stream code 00257 8d 42 01 lea eax, DWORD PTR [rdx+1] 0025a 44 3b d0 cmp r10d, eax 0025d 0f 84 38 01 00 00 je $LN70@stbi__proc ; 6295 : } ; 6296 : else if (code <= avail) { 00263 44 3b d6 cmp r10d, esi 00266 0f 8f 05 01 00 00 jg $LN19@stbi__proc ; 6297 : if (first) { 0026c 45 85 db test r11d, r11d 0026f 0f 85 d2 00 00 00 jne $LN71@stbi__proc ; 6299 : } ; 6300 : ; 6301 : if (oldcode >= 0) { 00275 45 85 f6 test r14d, r14d 00278 78 56 js SHORT $LN22@stbi__proc ; 6302 : p = &g->codes[avail++]; 0027a 4a 8d 14 85 00 00 00 00 lea rdx, QWORD PTR [r8*4] 00282 ff c6 inc esi 00284 49 ff c0 inc r8 00287 4c 89 44 24 28 mov QWORD PTR $T4[rsp], r8 ; 6303 : if (avail > 8192) { 0028c 81 fe 00 20 00 00 cmp esi, 8192 ; 00002000H 00292 0f 8f 85 00 00 00 jg $LN72@stbi__proc ; 6305 : } ; 6306 : ; 6307 : p->prefix = (stbi__int16)oldcode; ; 6308 : p->first = g->codes[oldcode].first; 00298 49 63 c6 movsxd rax, r14d 0029b 66 46 89 b4 2a 34 08 00 00 mov WORD PTR [rdx+r13+2100], r14w 002a4 41 0f b6 8c 85 36 08 00 00 movzx ecx, BYTE PTR [r13+rax*4+2102] 002ad 42 88 8c 2a 36 08 00 00 mov BYTE PTR [rdx+r13+2102], cl ; 6309 : p->suffix = (code == avail) ? p->first : g->codes[code].first; 002b5 44 3b d6 cmp r10d, esi 002b8 74 0c je SHORT $LN29@stbi__proc 002ba 49 63 c2 movsxd rax, r10d 002bd 41 0f b6 8c 85 36 08 00 00 movzx ecx, BYTE PTR [r13+rax*4+2102] $LN29@stbi__proc: 002c6 42 88 8c 2a 37 08 00 00 mov BYTE PTR [rdx+r13+2103], cl ; 6310 : } 002ce eb 09 jmp SHORT $LN25@stbi__proc $LN22@stbi__proc: ; 6311 : else if (code == avail) 002d0 44 3b d6 cmp r10d, esi 002d3 0f 84 98 00 00 00 je $LN19@stbi__proc $LN25@stbi__proc: ; 6312 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); ; 6313 : ; 6314 : stbi__out_gif_code(g, (stbi__uint16)code); 002d9 41 0f b7 d2 movzx edx, r10w 002dd 49 8b cd mov rcx, r13 002e0 e8 00 00 00 00 call stbi__out_gif_code ; 6315 : ; 6316 : if ((avail & codemask) == 0 && avail <= 0x0FFF) { 002e5 85 f5 test esi, ebp 002e7 75 17 jne SHORT $LN26@stbi__proc 002e9 81 fe ff 0f 00 00 cmp esi, 4095 ; 00000fffH 002ef 7f 0f jg SHORT $LN26@stbi__proc ; 6317 : codesize++; 002f1 41 ff c7 inc r15d ; 6318 : codemask = (1 << codesize) - 1; 002f4 bd 01 00 00 00 mov ebp, 1 002f9 41 8b cf mov ecx, r15d 002fc d3 e5 shl ebp, cl 002fe ff cd dec ebp $LN26@stbi__proc: ; 6325 : } ; 6326 : } ; 6327 : } 00300 8b 94 24 88 00 00 00 mov edx, DWORD PTR clear$1$[rsp] 00307 45 8b f2 mov r14d, r10d 0030a 4c 8b 44 24 28 mov r8, QWORD PTR $T4[rsp] 0030f 44 8b 4c 24 70 mov r9d, DWORD PTR bits$1$[rsp] 00314 8b 44 24 20 mov eax, DWORD PTR tv922[rsp] 00318 e9 d3 fd ff ff jmp $LL5@stbi__proc $LN72@stbi__proc: ; 431 : stbi__g_failure_reason = str; 0031d 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00323 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0032c b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00331 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00335 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0P@GJNJCPDJ@too?5many?5codes@ 0033c 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 6304 : return stbi__errpuc("too many codes", "Corrupt GIF"); 00340 33 c0 xor eax, eax 00342 e9 1b fe ff ff jmp $LN122@stbi__proc $LN71@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00347 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0034d 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00356 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0035b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0035f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@MGDACKOJ@no?5clear?5code@ 00366 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 6298 : return stbi__errpuc("no clear code", "Corrupt GIF"); 0036a 33 c0 xor eax, eax 0036c e9 f1 fd ff ff jmp $LN122@stbi__proc $LN19@stbi__proc: ; 431 : stbi__g_failure_reason = str; 00371 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00377 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00380 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00385 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00389 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BH@LOKBIIOJ@illegal?5code?5in?5raster@ 00390 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 6319 : } ; 6320 : ; 6321 : oldcode = code; ; 6322 : } ; 6323 : else { ; 6324 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); 00394 33 c0 xor eax, eax 00396 e9 c7 fd ff ff jmp $LN122@stbi__proc $LN70@stbi__proc: ; 1107 : if (n == 0) return; // already there! 0039b 85 ff test edi, edi 0039d 74 51 je SHORT $LL8@stbi__proc ; 1108 : if (n < 0) { 0039f 79 10 jns SHORT $LN44@stbi__proc ; 1109 : s->img_buffer = s->img_buffer_end; 003a1 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 003a8 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 1110 : return; 003af eb 3f jmp SHORT $LL8@stbi__proc $LN44@stbi__proc: ; 1111 : } ; 1112 : if (s->io.read) { 003b1 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 003b6 74 2b je SHORT $LN46@stbi__proc ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 003b8 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 003be 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 003c4 3b cf cmp ecx, edi 003c6 7d 1b jge SHORT $LN46@stbi__proc ; 1115 : s->img_buffer = s->img_buffer_end; 003c8 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 003cf 2b f9 sub edi, ecx 003d1 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 003d5 8b d7 mov edx, edi 003d7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003de ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 003e1 eb 0d jmp SHORT $LL8@stbi__proc $LN46@stbi__proc: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 003e3 48 63 c7 movsxd rax, edi 003e6 48 01 83 c0 00 00 00 add QWORD PTR [rbx+192], rax 003ed 0f 1f 00 npad 3 $LL8@stbi__proc: ; 1077 : if (s->img_buffer < s->img_buffer_end) 003f0 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] 003f7 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 003fe 73 0f jae SHORT $LN49@stbi__proc ; 1078 : return *s->img_buffer++; 00400 0f b6 11 movzx edx, BYTE PTR [rcx] 00403 48 ff c1 inc rcx 00406 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 0040d eb 27 jmp SHORT $LN48@stbi__proc $LN49@stbi__proc: ; 1079 : if (s->read_from_callbacks) { 0040f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00413 74 1f je SHORT $LN50@stbi__proc ; 1080 : stbi__refill_buffer(s); 00415 48 8b cb mov rcx, rbx 00418 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0041d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00424 0f b6 10 movzx edx, BYTE PTR [rax] 00427 48 8d 48 01 lea rcx, QWORD PTR [rax+1] 0042b 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00432 eb 02 jmp SHORT $LN48@stbi__proc $LN50@stbi__proc: ; 1082 : } ; 1083 : return 0; 00434 32 d2 xor dl, dl $LN48@stbi__proc: ; 6291 : stbi__skip(s, len); ; 6292 : while ((len = stbi__get8(s)) > 0) 00436 0f b6 d2 movzx edx, dl 00439 85 d2 test edx, edx 0043b 0f 84 1d fd ff ff je $LN9@stbi__proc ; 1112 : if (s->io.read) { 00441 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00446 74 2c je SHORT $LN56@stbi__proc ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00448 44 8b 83 c8 00 00 00 mov r8d, DWORD PTR [rbx+200] 0044f 44 2b c1 sub r8d, ecx ; 1114 : if (blen < n) { 00452 44 3b c2 cmp r8d, edx 00455 7d 1d jge SHORT $LN56@stbi__proc ; 1115 : s->img_buffer = s->img_buffer_end; 00457 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 0045e 41 2b d0 sub edx, r8d 00461 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 00465 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0046c ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 0046f e9 7c ff ff ff jmp $LL8@stbi__proc $LN56@stbi__proc: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 00474 48 8d 04 11 lea rax, QWORD PTR [rcx+rdx] 00478 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 6293 : stbi__skip(s, len); 0047f e9 6c ff ff ff jmp $LL8@stbi__proc stbi__process_gif_raster ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_load_next _TEXT SEGMENT s$ = 80 g$ = 88 comp$ = 96 first_frame$1$ = 104 req_comp$dead$ = 104 two_back$dead$ = 112 stbi__gif_load_next PROC ; COMDAT ; 6333 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 44 89 4c 24 20 mov DWORD PTR [rsp+32], r9d 00014 57 push rdi 00015 41 54 push r12 00017 41 55 push r13 00019 41 56 push r14 0001b 41 57 push r15 0001d 48 83 ec 20 sub rsp, 32 ; 00000020H ; 6334 : int dispose; ; 6335 : int first_frame; ; 6336 : int pi; ; 6337 : int pcount; ; 6338 : STBI_NOTUSED(req_comp); ; 6339 : ; 6340 : // on first frame, any non-written pixels get the background colour (non-transparent) ; 6341 : first_frame = 0; 00021 45 33 e4 xor r12d, r12d 00024 48 8b f2 mov rsi, rdx 00027 48 8b d9 mov rbx, rcx 0002a 44 89 64 24 68 mov DWORD PTR first_frame$1$[rsp], r12d ; 6342 : if (g->out == 0) { 0002f 4c 39 62 08 cmp QWORD PTR [rdx+8], r12 00033 0f 85 1f 01 00 00 jne $LN18@stbi__gif_ ; 6343 : if (!stbi__gif_header(s, g, comp, 0)) return 0; // stbi__g_failure_reason set by stbi__gif_header 00039 e8 00 00 00 00 call stbi__gif_header 0003e 85 c0 test eax, eax 00040 0f 84 a6 06 00 00 je $LN181@stbi__gif_ ; 6344 : if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) 00046 8b 0e mov ecx, DWORD PTR [rsi] 00048 8b 7e 04 mov edi, DWORD PTR [rsi+4] ; 467 : if (a < 0 || b < 0) return 0; 0004b 85 c9 test ecx, ecx 0004d 0f 88 e6 00 00 00 js $LN174@stbi__gif_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00053 75 0a jne SHORT $LN116@stbi__gif_ 00055 44 8d 04 8d 00 00 00 00 lea r8d, DWORD PTR [rcx*4] 0005d eb 22 jmp SHORT $LN178@stbi__gif_ $LN116@stbi__gif_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0005f b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00064 99 cdq 00065 f7 f9 idiv ecx ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00067 83 f8 04 cmp eax, 4 0006a 0f 8c c9 00 00 00 jl $LN174@stbi__gif_ 00070 44 8d 04 8d 00 00 00 00 lea r8d, DWORD PTR [rcx*4] ; 467 : if (a < 0 || b < 0) return 0; 00078 45 85 c0 test r8d, r8d 0007b 0f 88 b8 00 00 00 js $LN174@stbi__gif_ $LN178@stbi__gif_: 00081 85 ff test edi, edi 00083 0f 88 b0 00 00 00 js $LN174@stbi__gif_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00089 74 11 je SHORT $LN175@stbi__gif_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0008b b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00090 99 cdq 00091 f7 ff idiv edi ; 484 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00093 44 3b c0 cmp r8d, eax 00096 0f 8f 9d 00 00 00 jg $LN174@stbi__gif_ $LN175@stbi__gif_: ; 6344 : if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) 0009c 0f af f9 imul edi, ecx ; 6346 : pcount = g->w * g->h; ; 6347 : g->out = (stbi_uc*)stbi__malloc(4 * pcount); 0009f 8d 04 bd 00 00 00 00 lea eax, DWORD PTR [rdi*4] 000a6 48 63 e8 movsxd rbp, eax ; 438 : return STBI_MALLOC(size); 000a9 48 8b cd mov rcx, rbp 000ac ff 15 00 00 00 00 call QWORD PTR __imp_malloc 000b2 48 8b cd mov rcx, rbp ; 6346 : pcount = g->w * g->h; ; 6347 : g->out = (stbi_uc*)stbi__malloc(4 * pcount); 000b5 48 89 46 08 mov QWORD PTR [rsi+8], rax ; 438 : return STBI_MALLOC(size); 000b9 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 6349 : g->history = (stbi_uc*)stbi__malloc(pcount); 000bf 48 63 ff movsxd rdi, edi ; 438 : return STBI_MALLOC(size); 000c2 48 8b cf mov rcx, rdi ; 6348 : g->background = (stbi_uc*)stbi__malloc(4 * pcount); 000c5 48 89 46 10 mov QWORD PTR [rsi+16], rax ; 438 : return STBI_MALLOC(size); 000c9 ff 15 00 00 00 00 call QWORD PTR __imp_malloc ; 6350 : if (!g->out || !g->background || !g->history) 000cf 48 8b 4e 08 mov rcx, QWORD PTR [rsi+8] 000d3 48 89 46 18 mov QWORD PTR [rsi+24], rax 000d7 48 85 c9 test rcx, rcx 000da 74 3e je SHORT $LN23@stbi__gif_ 000dc 4c 39 66 10 cmp QWORD PTR [rsi+16], r12 000e0 74 38 je SHORT $LN23@stbi__gif_ 000e2 48 85 c0 test rax, rax 000e5 74 33 je SHORT $LN23@stbi__gif_ ; 6352 : ; 6353 : // image is treated as "transparent" at the start - ie, nothing overwrites the current background; ; 6354 : // background colour is only used for pixels that are not rendered first frame, after that "background" ; 6355 : // color refers to the color that was there the previous frame. ; 6356 : memset(g->out, 0x00, 4 * pcount); 000e7 4c 8b c5 mov r8, rbp 000ea 33 d2 xor edx, edx 000ec e8 00 00 00 00 call memset ; 6357 : memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) 000f1 48 8b 4e 10 mov rcx, QWORD PTR [rsi+16] 000f5 4c 8b c5 mov r8, rbp 000f8 33 d2 xor edx, edx 000fa e8 00 00 00 00 call memset ; 6358 : memset(g->history, 0x00, pcount); // pixels that were affected previous frame 000ff 48 8b 4e 18 mov rcx, QWORD PTR [rsi+24] 00103 4c 8b c7 mov r8, rdi 00106 33 d2 xor edx, edx 00108 e8 00 00 00 00 call memset ; 6359 : first_frame = 1; 0010d c7 44 24 68 01 00 00 00 mov DWORD PTR first_frame$1$[rsp], 1 ; 6360 : } 00115 e9 9f 00 00 00 jmp $LN19@stbi__gif_ $LN23@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 0011a 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00120 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00129 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0012d 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ ; 6351 : return stbi__errpuc("outofmem", "Out of memory"); 00134 e9 aa 05 00 00 jmp $LN236@stbi__gif_ $LN174@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 00139 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0013f 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00148 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0014c 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ ; 6345 : return stbi__errpuc("too large", "GIF image is too large"); 00153 e9 8b 05 00 00 jmp $LN236@stbi__gif_ $LN18@stbi__gif_: ; 6361 : else { ; 6362 : // second frame - how do we dispose of the previous one? ; 6363 : dispose = (g->eflags & 0x1C) >> 2; ; 6364 : pcount = g->w * g->h; 00158 8b 02 mov eax, DWORD PTR [rdx] 0015a 0f af 42 04 imul eax, DWORD PTR [rdx+4] 0015e 8b 4a 30 mov ecx, DWORD PTR [rdx+48] 00161 4c 63 c0 movsxd r8, eax ; 6365 : ; 6366 : if ((dispose == 3) && (two_back == 0)) { 00164 8b c1 mov eax, ecx 00166 83 e0 1c and eax, 28 00169 3c 0c cmp al, 12 0016b 74 08 je SHORT $LN177@stbi__gif_ ; 6367 : dispose = 2; // if I don't have an image to revert back to, default to the old background ; 6368 : } ; 6369 : ; 6370 : if (dispose == 3) { // use previous graphic ; 6371 : for (pi = 0; pi < pcount; ++pi) { ; 6372 : if (g->history[pi]) { ; 6373 : memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); ; 6374 : } ; 6375 : } ; 6376 : } ; 6377 : else if (dispose == 2) { 0016d 80 e1 1c and cl, 28 00170 80 f9 08 cmp cl, 8 00173 75 2b jne SHORT $LN6@stbi__gif_ $LN177@stbi__gif_: ; 6378 : // restore what was changed last frame to background before that frame; ; 6379 : for (pi = 0; pi < pcount; ++pi) { 00175 4d 85 c0 test r8, r8 00178 7e 26 jle SHORT $LN6@stbi__gif_ 0017a 49 8b d4 mov rdx, r12 0017d 0f 1f 00 npad 3 $LL7@stbi__gif_: ; 6380 : if (g->history[pi]) { 00180 48 8b 46 18 mov rax, QWORD PTR [rsi+24] 00184 44 38 24 02 cmp BYTE PTR [rdx+rax], r12b 00188 74 0e je SHORT $LN5@stbi__gif_ ; 6381 : memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); 0018a 48 8b 46 10 mov rax, QWORD PTR [rsi+16] 0018e 48 8b 4e 08 mov rcx, QWORD PTR [rsi+8] 00192 8b 04 90 mov eax, DWORD PTR [rax+rdx*4] 00195 89 04 91 mov DWORD PTR [rcx+rdx*4], eax $LN5@stbi__gif_: ; 6378 : // restore what was changed last frame to background before that frame; ; 6379 : for (pi = 0; pi < pcount; ++pi) { 00198 48 ff c2 inc rdx 0019b 49 3b d0 cmp rdx, r8 0019e 7c e0 jl SHORT $LL7@stbi__gif_ $LN6@stbi__gif_: ; 6382 : } ; 6383 : } ; 6384 : } ; 6385 : else { ; 6386 : // This is a non-disposal case eithe way, so just ; 6387 : // leave the pixels as is, and they will become the new background ; 6388 : // 1: do not dispose ; 6389 : // 0: not specified. ; 6390 : } ; 6391 : ; 6392 : // background is what out is after the undoing of the previou frame; ; 6393 : memcpy(g->background, g->out, 4 * g->w * g->h); 001a0 8b 46 04 mov eax, DWORD PTR [rsi+4] 001a3 0f af 06 imul eax, DWORD PTR [rsi] 001a6 48 8b 56 08 mov rdx, QWORD PTR [rsi+8] 001aa 48 8b 4e 10 mov rcx, QWORD PTR [rsi+16] 001ae c1 e0 02 shl eax, 2 001b1 4c 63 c0 movsxd r8, eax 001b4 e8 00 00 00 00 call memcpy $LN19@stbi__gif_: ; 6394 : } ; 6395 : ; 6396 : // clear my history; ; 6397 : memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame 001b9 8b 46 04 mov eax, DWORD PTR [rsi+4] 001bc 33 d2 xor edx, edx 001be 0f af 06 imul eax, DWORD PTR [rsi] 001c1 48 8b 4e 18 mov rcx, QWORD PTR [rsi+24] 001c5 4c 63 c0 movsxd r8, eax 001c8 e8 00 00 00 00 call memset 001cd 41 bd ff ff ff ff mov r13d, -1 $LN85@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 001d3 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 001d7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL8@stbi__gif_: 001e0 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] 001e7 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 001ee 73 08 jae SHORT $LN68@stbi__gif_ ; 1078 : return *s->img_buffer++; 001f0 0f b6 11 movzx edx, BYTE PTR [rcx] 001f3 48 ff c1 inc rcx 001f6 eb 24 jmp SHORT $LN237@stbi__gif_ $LN68@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 001f8 44 39 63 30 cmp DWORD PTR [rbx+48], r12d 001fc 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 00200 0f 84 c3 04 00 00 je $LN180@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00206 48 8b cb mov rcx, rbx 00209 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0020e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00215 0f b6 10 movzx edx, BYTE PTR [rax] 00218 48 8d 48 01 lea rcx, QWORD PTR [rax+1] $LN237@stbi__gif_: ; 6398 : ; 6399 : for (;;) { ; 6400 : int tag = stbi__get8(s); ; 6401 : switch (tag) { 0021c 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00223 80 fa 21 cmp dl, 33 ; 00000021H 00226 0f 85 81 02 00 00 jne $LN142@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0022c 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 00233 73 08 jae SHORT $LN72@stbi__gif_ ; 1078 : return *s->img_buffer++; 00235 0f b6 11 movzx edx, BYTE PTR [rcx] 00238 48 ff c1 inc rcx 0023b eb 1f jmp SHORT $LN238@stbi__gif_ $LN72@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 0023d 44 39 27 cmp DWORD PTR [rdi], r12d 00240 0f 84 36 01 00 00 je $LN169@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00246 48 8b cb mov rcx, rbx 00249 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0024e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00255 0f b6 10 movzx edx, BYTE PTR [rax] 00258 48 8d 48 01 lea rcx, QWORD PTR [rax+1] $LN238@stbi__gif_: ; 6466 : } ; 6467 : ; 6468 : case 0x21: // Comment Extension. ; 6469 : { ; 6470 : int len; ; 6471 : int ext = stbi__get8(s); ; 6472 : if (ext == 0xF9) { // Graphic Control Extension. 0025c 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00263 80 fa f9 cmp dl, 249 ; 000000f9H 00266 0f 85 10 01 00 00 jne $LN169@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0026c 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 00273 73 0f jae SHORT $LN76@stbi__gif_ ; 1078 : return *s->img_buffer++; 00275 0f b6 11 movzx edx, BYTE PTR [rcx] 00278 48 ff c1 inc rcx 0027b 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00282 eb 26 jmp SHORT $LN75@stbi__gif_ $LN76@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 00284 44 39 27 cmp DWORD PTR [rdi], r12d 00287 74 1f je SHORT $LN77@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00289 48 8b cb mov rcx, rbx 0028c e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00291 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00298 0f b6 10 movzx edx, BYTE PTR [rax] 0029b 48 8d 48 01 lea rcx, QWORD PTR [rax+1] 0029f 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 002a6 eb 02 jmp SHORT $LN75@stbi__gif_ $LN77@stbi__gif_: ; 1082 : } ; 1083 : return 0; 002a8 32 d2 xor dl, dl $LN75@stbi__gif_: ; 6473 : len = stbi__get8(s); 002aa 0f b6 d2 movzx edx, dl ; 6474 : if (len == 4) { 002ad 83 fa 04 cmp edx, 4 002b0 0f 85 3a 01 00 00 jne $LN46@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 002b6 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 002bd 73 10 jae SHORT $LN82@stbi__gif_ ; 1078 : return *s->img_buffer++; 002bf 0f b6 11 movzx edx, BYTE PTR [rcx] 002c2 48 8d 41 01 lea rax, QWORD PTR [rcx+1] 002c6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002cd eb 26 jmp SHORT $LN239@stbi__gif_ $LN82@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 002cf 44 39 63 30 cmp DWORD PTR [rbx+48], r12d 002d3 74 1e je SHORT $LN83@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 002d5 48 8b cb mov rcx, rbx 002d8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 002dd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002e4 0f b6 10 movzx edx, BYTE PTR [rax] 002e7 48 ff c0 inc rax 002ea 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 002f1 eb 02 jmp SHORT $LN239@stbi__gif_ $LN83@stbi__gif_: ; 1082 : } ; 1083 : return 0; 002f3 32 d2 xor dl, dl $LN239@stbi__gif_: ; 6475 : g->eflags = stbi__get8(s); 002f5 b9 30 00 00 00 mov ecx, 48 ; 00000030H 002fa 48 8b c3 mov rax, rbx 002fd 0f b6 c2 movzx eax, dl 00300 89 46 30 mov DWORD PTR [rsi+48], eax 00303 48 8d 3c 0b lea rdi, QWORD PTR [rbx+rcx] ; 6476 : g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. 00307 48 8b cb mov rcx, rbx 0030a e8 00 00 00 00 call stbi__get16le 0030f 8d 0c 80 lea ecx, DWORD PTR [rax+rax*4] ; 6477 : ; 6478 : // unset old transparent ; 6479 : if (g->transparent >= 0) { 00312 48 63 46 2c movsxd rax, DWORD PTR [rsi+44] 00316 03 c9 add ecx, ecx 00318 89 8e 68 88 00 00 mov DWORD PTR [rsi+34920], ecx 0031e 85 c0 test eax, eax 00320 78 05 js SHORT $LN48@stbi__gif_ ; 6480 : g->pal[g->transparent][3] = 255; 00322 c6 44 86 37 ff mov BYTE PTR [rsi+rax*4+55], 255 ; 000000ffH $LN48@stbi__gif_: ; 6481 : } ; 6482 : if (g->eflags & 0x01) { 00327 f6 46 30 01 test BYTE PTR [rsi+48], 1 0032b 74 7d je SHORT $LN49@stbi__gif_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0032d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00334 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0033b 73 0f jae SHORT $LN94@stbi__gif_ ; 1078 : return *s->img_buffer++; 0033d 0f b6 08 movzx ecx, BYTE PTR [rax] 00340 48 ff c0 inc rax 00343 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0034a eb 25 jmp SHORT $LN93@stbi__gif_ $LN94@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 0034c 44 39 27 cmp DWORD PTR [rdi], r12d 0034f 74 1e je SHORT $LN95@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 00351 48 8b cb mov rcx, rbx 00354 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00359 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00360 0f b6 08 movzx ecx, BYTE PTR [rax] 00363 48 ff c0 inc rax 00366 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0036d eb 02 jmp SHORT $LN93@stbi__gif_ $LN95@stbi__gif_: ; 1082 : } ; 1083 : return 0; 0036f 32 c9 xor cl, cl $LN93@stbi__gif_: ; 6483 : g->transparent = stbi__get8(s); 00371 0f b6 c1 movzx eax, cl 00374 89 46 2c mov DWORD PTR [rsi+44], eax ; 6484 : if (g->transparent >= 0) { ; 6485 : g->pal[g->transparent][3] = 0; 00377 44 88 64 86 37 mov BYTE PTR [rsi+rax*4+55], r12b $LN169@stbi__gif_: ; 6381 : memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); 0037c 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] $LL16@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00380 48 8b 8b c0 00 00 00 mov rcx, QWORD PTR [rbx+192] 00387 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 0038e 0f 83 a6 00 00 00 jae $LN58@stbi__gif_ ; 1078 : return *s->img_buffer++; 00394 0f b6 11 movzx edx, BYTE PTR [rcx] 00397 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 0039b 48 ff c1 inc rcx 0039e 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 003a5 e9 b6 00 00 00 jmp $LN57@stbi__gif_ $LN49@stbi__gif_: ; 1112 : if (s->io.read) { 003aa 4c 39 63 10 cmp QWORD PTR [rbx+16], r12 003ae 74 33 je SHORT $LN173@stbi__gif_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 003b0 8b 8b c8 00 00 00 mov ecx, DWORD PTR [rbx+200] 003b6 2b 8b c0 00 00 00 sub ecx, DWORD PTR [rbx+192] ; 1114 : if (blen < n) { 003bc 83 f9 01 cmp ecx, 1 003bf 7d 22 jge SHORT $LN173@stbi__gif_ ; 1115 : s->img_buffer = s->img_buffer_end; 003c1 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 003c8 ba 01 00 00 00 mov edx, 1 003cd 2b d1 sub edx, ecx 003cf 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003d6 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 003da ff 53 18 call QWORD PTR [rbx+24] ; 6486 : } ; 6487 : } ; 6488 : else { ; 6489 : // don't need transparent ; 6490 : stbi__skip(s, 1); ; 6491 : g->transparent = -1; 003dd 44 89 6e 2c mov DWORD PTR [rsi+44], r13d ; 6492 : } ; 6493 : } 003e1 eb 99 jmp SHORT $LN169@stbi__gif_ $LN173@stbi__gif_: ; 1120 : s->img_buffer += n; 003e3 48 ff 83 c0 00 00 00 inc QWORD PTR [rbx+192] ; 6486 : } ; 6487 : } ; 6488 : else { ; 6489 : // don't need transparent ; 6490 : stbi__skip(s, 1); ; 6491 : g->transparent = -1; 003ea 44 89 6e 2c mov DWORD PTR [rsi+44], r13d ; 6492 : } ; 6493 : } 003ee eb 8c jmp SHORT $LN169@stbi__gif_ $LN46@stbi__gif_: ; 1107 : if (n == 0) return; // already there! 003f0 85 d2 test edx, edx 003f2 0f 84 db fd ff ff je $LN85@stbi__gif_ ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { 003f8 4c 39 63 10 cmp QWORD PTR [rbx+16], r12 003fc 74 2c je SHORT $LN89@stbi__gif_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 003fe 44 8b 83 c8 00 00 00 mov r8d, DWORD PTR [rbx+200] 00405 44 2b c1 sub r8d, ecx ; 1114 : if (blen < n) { 00408 44 3b c2 cmp r8d, edx 0040b 7d 1d jge SHORT $LN89@stbi__gif_ ; 1115 : s->img_buffer = s->img_buffer_end; 0040d 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00414 41 2b d0 sub edx, r8d 00417 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0041b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00422 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 00425 e9 a9 fd ff ff jmp $LN85@stbi__gif_ $LN89@stbi__gif_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0042a 48 8d 04 11 lea rax, QWORD PTR [rcx+rdx] 0042e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 6494 : else { ; 6495 : stbi__skip(s, len); ; 6496 : break; 00435 e9 99 fd ff ff jmp $LN85@stbi__gif_ $LN58@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 0043a 44 39 27 cmp DWORD PTR [rdi], r12d 0043d 74 1f je SHORT $LN59@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 0043f 48 8b cb mov rcx, rbx 00442 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00447 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0044e 0f b6 10 movzx edx, BYTE PTR [rax] 00451 48 8d 48 01 lea rcx, QWORD PTR [rax+1] 00455 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 0045c eb 02 jmp SHORT $LN57@stbi__gif_ $LN59@stbi__gif_: ; 1082 : } ; 1083 : return 0; 0045e 32 d2 xor dl, dl $LN57@stbi__gif_: ; 6497 : } ; 6498 : } ; 6499 : while ((len = stbi__get8(s)) != 0) { 00460 0f b6 d2 movzx edx, dl 00463 85 d2 test edx, edx 00465 0f 84 75 fd ff ff je $LL8@stbi__gif_ ; 1112 : if (s->io.read) { 0046b 4c 39 63 10 cmp QWORD PTR [rbx+16], r12 0046f 74 2c je SHORT $LN65@stbi__gif_ ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00471 44 8b 83 c8 00 00 00 mov r8d, DWORD PTR [rbx+200] 00478 44 2b c1 sub r8d, ecx ; 1114 : if (blen < n) { 0047b 44 3b c2 cmp r8d, edx 0047e 7d 1d jge SHORT $LN65@stbi__gif_ ; 1115 : s->img_buffer = s->img_buffer_end; 00480 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1116 : (s->io.skip)(s->io_user_data, n - blen); 00487 41 2b d0 sub edx, r8d 0048a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0048e 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00495 ff 53 18 call QWORD PTR [rbx+24] ; 1117 : return; 00498 e9 e3 fe ff ff jmp $LL16@stbi__gif_ $LN65@stbi__gif_: ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; 0049d 48 8d 04 11 lea rax, QWORD PTR [rcx+rdx] 004a1 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 6500 : stbi__skip(s, len); ; 6501 : } 004a8 e9 d3 fe ff ff jmp $LL16@stbi__gif_ $LN142@stbi__gif_: ; 6398 : ; 6399 : for (;;) { ; 6400 : int tag = stbi__get8(s); ; 6401 : switch (tag) { 004ad 80 fa 2c cmp dl, 44 ; 0000002cH 004b0 74 11 je SHORT $LN31@stbi__gif_ 004b2 80 fa 3b cmp dl, 59 ; 0000003bH 004b5 0f 85 0e 02 00 00 jne $LN180@stbi__gif_ ; 6502 : break; ; 6503 : } ; 6504 : ; 6505 : case 0x3B: // gif stream termination code ; 6506 : return (stbi_uc*)s; // using '1' causes warning on some compilers 004bb 48 8b c3 mov rax, rbx 004be e9 2b 02 00 00 jmp $LN9@stbi__gif_ $LN31@stbi__gif_: ; 6402 : case 0x2C: /* Image Descriptor */ ; 6403 : { ; 6404 : stbi__int32 x, y, w, h; ; 6405 : stbi_uc* o; ; 6406 : ; 6407 : x = stbi__get16le(s); 004c3 48 8b cb mov rcx, rbx 004c6 e8 00 00 00 00 call stbi__get16le ; 6408 : y = stbi__get16le(s); 004cb 48 8b cb mov rcx, rbx 004ce 44 8b f8 mov r15d, eax 004d1 e8 00 00 00 00 call stbi__get16le ; 6409 : w = stbi__get16le(s); 004d6 48 8b cb mov rcx, rbx 004d9 8b e8 mov ebp, eax 004db e8 00 00 00 00 call stbi__get16le ; 6410 : h = stbi__get16le(s); 004e0 48 8b cb mov rcx, rbx 004e3 44 8b f0 mov r14d, eax 004e6 e8 00 00 00 00 call stbi__get16le ; 6411 : if (((x + w) > (g->w)) || ((y + h) > (g->h))) 004eb 44 8b 06 mov r8d, DWORD PTR [rsi] 004ee 43 8d 0c 3e lea ecx, DWORD PTR [r14+r15] 004f2 44 8b c8 mov r9d, eax 004f5 41 3b c8 cmp ecx, r8d 004f8 0f 8f af 01 00 00 jg $LN33@stbi__gif_ 004fe 8d 0c 28 lea ecx, DWORD PTR [rax+rbp] 00501 3b 4e 04 cmp ecx, DWORD PTR [rsi+4] 00504 0f 8f a3 01 00 00 jg $LN33@stbi__gif_ ; 6413 : ; 6414 : g->line_size = g->w * 4; 0050a 46 8d 04 85 00 00 00 00 lea r8d, DWORD PTR [r8*4] ; 6415 : g->start_x = x * 4; 00512 42 8d 0c bd 00 00 00 00 lea ecx, DWORD PTR [r15*4] 0051a 44 89 86 64 88 00 00 mov DWORD PTR [rsi+34916], r8d ; 6416 : g->start_y = y * g->line_size; 00521 41 8b d0 mov edx, r8d 00524 89 8e 4c 88 00 00 mov DWORD PTR [rsi+34892], ecx 0052a 0f af d5 imul edx, ebp ; 6417 : g->max_x = g->start_x + w * 4; 0052d 42 8d 04 b1 lea eax, DWORD PTR [rcx+r14*4] ; 6418 : g->max_y = g->start_y + h * g->line_size; 00531 45 0f af c1 imul r8d, r9d 00535 89 86 54 88 00 00 mov DWORD PTR [rsi+34900], eax ; 6419 : g->cur_x = g->start_x; 0053b 89 8e 5c 88 00 00 mov DWORD PTR [rsi+34908], ecx 00541 89 96 50 88 00 00 mov DWORD PTR [rsi+34896], edx ; 6420 : g->cur_y = g->start_y; 00547 89 96 60 88 00 00 mov DWORD PTR [rsi+34912], edx 0054d 41 8d 04 10 lea eax, DWORD PTR [r8+rdx] 00551 89 86 58 88 00 00 mov DWORD PTR [rsi+34904], eax ; 6421 : ; 6422 : // if the width of the specified rectangle is 0, that means ; 6423 : // we may not see *any* pixels or the image is malformed; ; 6424 : // to make sure this is caught, move the current y down to ; 6425 : // max_y (which is what out_gif_code checks). ; 6426 : if (w == 0) 00557 45 85 f6 test r14d, r14d 0055a 75 0a jne SHORT $LN34@stbi__gif_ ; 6427 : g->cur_y = g->max_y; 0055c 89 86 60 88 00 00 mov DWORD PTR [rsi+34912], eax 00562 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] $LN34@stbi__gif_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00566 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0056d 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00574 73 0f jae SHORT $LN98@stbi__gif_ ; 1078 : return *s->img_buffer++; 00576 0f b6 08 movzx ecx, BYTE PTR [rax] 00579 48 ff c0 inc rax 0057c 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00583 eb 25 jmp SHORT $LN97@stbi__gif_ $LN98@stbi__gif_: ; 1079 : if (s->read_from_callbacks) { 00585 44 39 27 cmp DWORD PTR [rdi], r12d 00588 74 1e je SHORT $LN99@stbi__gif_ ; 1080 : stbi__refill_buffer(s); 0058a 48 8b cb mov rcx, rbx 0058d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00592 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00599 0f b6 08 movzx ecx, BYTE PTR [rax] 0059c 48 ff c0 inc rax 0059f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 005a6 eb 02 jmp SHORT $LN97@stbi__gif_ $LN99@stbi__gif_: ; 1082 : } ; 1083 : return 0; 005a8 32 c9 xor cl, cl $LN97@stbi__gif_: ; 6428 : ; 6429 : g->lflags = stbi__get8(s); 005aa 44 0f b6 c9 movzx r9d, cl ; 6430 : ; 6431 : if (g->lflags & 0x40) { 005ae 8b 8e 64 88 00 00 mov ecx, DWORD PTR [rsi+34916] 005b4 41 8b d1 mov edx, r9d 005b7 83 e2 40 and edx, 64 ; 00000040H 005ba 44 89 8e 48 88 00 00 mov DWORD PTR [rsi+34888], r9d ; 6432 : g->step = 8 * g->line_size; // first interlaced spacing ; 6433 : g->parse = 3; ; 6434 : } ; 6435 : else { ; 6436 : g->step = g->line_size; ; 6437 : g->parse = 0; ; 6438 : } ; 6439 : ; 6440 : if (g->lflags & 0x80) { 005c1 8d 04 cd 00 00 00 00 lea eax, DWORD PTR [rcx*8] 005c8 0f 44 c1 cmove eax, ecx 005cb f7 da neg edx 005cd 89 86 44 88 00 00 mov DWORD PTR [rsi+34884], eax 005d3 1b c0 sbb eax, eax 005d5 83 e0 03 and eax, 3 005d8 89 86 40 88 00 00 mov DWORD PTR [rsi+34880], eax 005de 45 84 c9 test r9b, r9b 005e1 79 32 jns SHORT $LN37@stbi__gif_ ; 6441 : stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); 005e3 f6 46 30 01 test BYTE PTR [rsi+48], 1 005e7 74 04 je SHORT $LN55@stbi__gif_ 005e9 44 8b 6e 2c mov r13d, DWORD PTR [rsi+44] $LN55@stbi__gif_: 005ed 41 83 e1 07 and r9d, 7 005f1 48 8d be 34 04 00 00 lea rdi, QWORD PTR [rsi+1076] 005f8 41 0f b6 c9 movzx ecx, r9b 005fc 41 b8 02 00 00 00 mov r8d, 2 00602 41 d3 e0 shl r8d, cl 00605 45 8b cd mov r9d, r13d 00608 48 8b cb mov rcx, rbx 0060b 48 8b d7 mov rdx, rdi 0060e e8 00 00 00 00 call stbi__gif_parse_colortable ; 6442 : g->color_table = (stbi_uc*)g->lpal; ; 6443 : } 00613 eb 0a jmp SHORT $LN40@stbi__gif_ $LN37@stbi__gif_: ; 6444 : else if (g->flags & 0x80) { 00615 f6 46 20 80 test BYTE PTR [rsi+32], 128 ; 00000080H 00619 74 76 je SHORT $LN39@stbi__gif_ ; 6445 : g->color_table = (stbi_uc*)g->pal; 0061b 48 8d 7e 34 lea rdi, QWORD PTR [rsi+52] $LN40@stbi__gif_: ; 6449 : ; 6450 : o = stbi__process_gif_raster(s, g); 0061f 48 8b d6 mov rdx, rsi 00622 48 89 be 38 88 00 00 mov QWORD PTR [rsi+34872], rdi 00629 48 8b cb mov rcx, rbx 0062c e8 00 00 00 00 call stbi__process_gif_raster 00631 4c 8b c0 mov r8, rax ; 6451 : if (!o) return NULL; 00634 48 85 c0 test rax, rax 00637 0f 84 af 00 00 00 je $LN181@stbi__gif_ ; 6455 : if (first_frame && (g->bgindex > 0)) { 0063d 44 39 64 24 68 cmp DWORD PTR first_frame$1$[rsp], r12d 00642 74 48 je SHORT $LN14@stbi__gif_ 00644 44 39 66 24 cmp DWORD PTR [rsi+36], r12d 00648 7e 42 jle SHORT $LN14@stbi__gif_ ; 6452 : ; 6453 : // if this was the first frame, ; 6454 : pcount = g->w * g->h; 0064a 8b 46 04 mov eax, DWORD PTR [rsi+4] 0064d 0f af 06 imul eax, DWORD PTR [rsi] ; 6456 : // if first frame, any pixel not drawn to gets the background color ; 6457 : for (pi = 0; pi < pcount; ++pi) { 00650 48 63 d0 movsxd rdx, eax 00653 85 c0 test eax, eax 00655 7e 35 jle SHORT $LN14@stbi__gif_ 00657 66 0f 1f 84 00 00 00 00 00 npad 9 $LL15@stbi__gif_: ; 6458 : if (g->history[pi] == 0) { 00660 48 8b 46 18 mov rax, QWORD PTR [rsi+24] 00664 41 80 3c 04 00 cmp BYTE PTR [r12+rax], 0 00669 75 19 jne SHORT $LN13@stbi__gif_ ; 6459 : g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; 0066b 48 63 46 24 movsxd rax, DWORD PTR [rsi+36] 0066f c6 44 86 37 ff mov BYTE PTR [rsi+rax*4+55], 255 ; 000000ffH ; 6460 : memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); 00674 48 63 46 24 movsxd rax, DWORD PTR [rsi+36] 00678 48 8b 4e 08 mov rcx, QWORD PTR [rsi+8] 0067c 8b 44 86 34 mov eax, DWORD PTR [rsi+rax*4+52] 00680 42 89 04 a1 mov DWORD PTR [rcx+r12*4], eax $LN13@stbi__gif_: ; 6456 : // if first frame, any pixel not drawn to gets the background color ; 6457 : for (pi = 0; pi < pcount; ++pi) { 00684 49 ff c4 inc r12 00687 4c 3b e2 cmp r12, rdx 0068a 7c d4 jl SHORT $LL15@stbi__gif_ $LN14@stbi__gif_: ; 6461 : } ; 6462 : } ; 6463 : } ; 6464 : ; 6465 : return o; 0068c 49 8b c0 mov rax, r8 0068f eb 5d jmp SHORT $LN9@stbi__gif_ $LN39@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 00691 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00697 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006a0 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006a4 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BE@NAMJKDNF@missing?5color?5table@ ; 6446 : } ; 6447 : else ; 6448 : return stbi__errpuc("missing color table", "Corrupt GIF"); 006ab eb 36 jmp SHORT $LN236@stbi__gif_ $LN33@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 006ad 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 006b3 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006bc 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006c0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BF@GIAALCNJ@bad?5Image?5Descriptor@ ; 6412 : return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); 006c7 eb 1a jmp SHORT $LN236@stbi__gif_ $LN180@stbi__gif_: ; 431 : stbi__g_failure_reason = str; 006c9 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 006cf 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006d8 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006dc 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0N@DJABBOOH@unknown?5code@ $LN236@stbi__gif_: ; 6507 : ; 6508 : default: ; 6509 : return stbi__errpuc("unknown code", "Corrupt GIF"); ; 6510 : } ; 6511 : } ; 6512 : } 006e3 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 006e8 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN181@stbi__gif_: 006ec 33 c0 xor eax, eax $LN9@stbi__gif_: 006ee 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 006f3 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 006f8 48 8b 74 24 60 mov rsi, QWORD PTR [rsp+96] 006fd 48 83 c4 20 add rsp, 32 ; 00000020H 00701 41 5f pop r15 00703 41 5e pop r14 00705 41 5d pop r13 00707 41 5c pop r12 00709 5f pop rdi 0070a c3 ret 0 stbi__gif_load_next ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__gif_load _TEXT SEGMENT g$ = 48 __$ArrayPad$ = 34976 s$ = 35056 x$ = 35064 y$ = 35072 comp$ = 35080 req_comp$ = 35088 ri$dead$ = 35096 stbi__gif_load PROC ; COMDAT ; 6613 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 56 push r14 00007 41 57 push r15 00009 b8 b8 88 00 00 mov eax, 35000 ; 000088b8H 0000e e8 00 00 00 00 call __chkstk 00013 48 2b e0 sub rsp, rax 00016 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 0001d 48 33 c4 xor rax, rsp 00020 48 89 84 24 a0 88 00 00 mov QWORD PTR __$ArrayPad$[rsp], rax 00028 8b ac 24 10 89 00 00 mov ebp, DWORD PTR req_comp$[rsp] 0002f 4d 8b f8 mov r15, r8 00032 4c 8b f2 mov r14, rdx 00035 48 8b f9 mov rdi, rcx ; 6614 : stbi_uc* u = 0; ; 6615 : stbi__gif g; ; 6616 : memset(&g, 0, sizeof(g)); 00038 33 d2 xor edx, edx 0003a 48 8d 4c 24 30 lea rcx, QWORD PTR g$[rsp] 0003f 41 b8 70 88 00 00 mov r8d, 34928 ; 00008870H 00045 49 8b d9 mov rbx, r9 00048 e8 00 00 00 00 call memset ; 6617 : STBI_NOTUSED(ri); ; 6618 : ; 6619 : u = stbi__gif_load_next(s, &g, comp, req_comp, 0); 0004d 33 f6 xor esi, esi 0004f 48 8d 54 24 30 lea rdx, QWORD PTR g$[rsp] 00054 44 8b cd mov r9d, ebp 00057 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi 0005c 4c 8b c3 mov r8, rbx 0005f 48 8b cf mov rcx, rdi 00062 e8 00 00 00 00 call stbi__gif_load_next ; 6620 : if (u == (stbi_uc*)s) u = 0; // end of animated gif marker ; 6621 : if (u) { 00067 48 3b c7 cmp rax, rdi 0006a 48 0f 45 f0 cmovne rsi, rax 0006e 48 8b de mov rbx, rsi 00071 48 85 f6 test rsi, rsi 00074 74 31 je SHORT $LN3@stbi__gif_ ; 6622 : *x = g.w; 00076 44 8b 4c 24 30 mov r9d, DWORD PTR g$[rsp] ; 6623 : *y = g.h; 0007b 8b 44 24 34 mov eax, DWORD PTR g$[rsp+4] 0007f 45 89 0e mov DWORD PTR [r14], r9d 00082 41 89 07 mov DWORD PTR [r15], eax ; 6624 : ; 6625 : // moved conversion to after successful load so that the same ; 6626 : // can be done for multiple frames. ; 6627 : if (req_comp && req_comp != 4) 00085 85 ed test ebp, ebp 00087 74 2e je SHORT $LN6@stbi__gif_ 00089 83 fd 04 cmp ebp, 4 0008c 74 29 je SHORT $LN6@stbi__gif_ ; 6628 : u = stbi__convert_format(u, 4, req_comp, g.w, g.h); 0008e 44 8b c5 mov r8d, ebp 00091 89 44 24 20 mov DWORD PTR [rsp+32], eax 00095 ba 04 00 00 00 mov edx, 4 0009a 48 8b ce mov rcx, rsi 0009d e8 00 00 00 00 call stbi__convert_format 000a2 48 8b d8 mov rbx, rax ; 6629 : } 000a5 eb 10 jmp SHORT $LN6@stbi__gif_ $LN3@stbi__gif_: ; 6630 : else if (g.out) { 000a7 48 8b 4c 24 38 mov rcx, QWORD PTR g$[rsp+8] 000ac 48 85 c9 test rcx, rcx 000af 74 06 je SHORT $LN6@stbi__gif_ ; 6631 : // if there was an error and we allocated an image buffer, free it! ; 6632 : STBI_FREE(g.out); 000b1 ff 15 00 00 00 00 call QWORD PTR __imp_free $LN6@stbi__gif_: ; 6633 : } ; 6634 : ; 6635 : // free buffers needed for multiple frame loading; ; 6636 : STBI_FREE(g.history); 000b7 48 8b 4c 24 48 mov rcx, QWORD PTR g$[rsp+24] 000bc ff 15 00 00 00 00 call QWORD PTR __imp_free ; 6637 : STBI_FREE(g.background); 000c2 48 8b 4c 24 40 mov rcx, QWORD PTR g$[rsp+16] 000c7 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 6638 : ; 6639 : return u; 000cd 48 8b c3 mov rax, rbx ; 6640 : } 000d0 48 8b 8c 24 a0 88 00 00 mov rcx, QWORD PTR __$ArrayPad$[rsp] 000d8 48 33 cc xor rcx, rsp 000db e8 00 00 00 00 call __security_check_cookie 000e0 48 81 c4 b8 88 00 00 add rsp, 35000 ; 000088b8H 000e7 41 5f pop r15 000e9 41 5e pop r14 000eb 5f pop rdi 000ec 5e pop rsi 000ed 5d pop rbp 000ee 5b pop rbx 000ef c3 ret 0 stbi__gif_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_test_core _TEXT SEGMENT s$ = 48 signature$ = 56 stbi__hdr_test_core PROC ; COMDAT ; 6653 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H ; 6654 : int i; ; 6655 : for (i = 0; signature[i]; ++i) 0000f 80 3a 00 cmp BYTE PTR [rdx], 0 00012 48 8b da mov rbx, rdx 00015 48 8b f9 mov rdi, rcx 00018 74 5d je SHORT $LN18@stbi__hdr_ 0001a 66 0f 1f 44 00 00 npad 6 $LL4@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00020 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00027 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0002e 73 0f jae SHORT $LN8@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00030 0f b6 08 movzx ecx, BYTE PTR [rax] 00033 48 ff c0 inc rax 00036 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 0003d eb 26 jmp SHORT $LN7@stbi__hdr_ $LN8@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 0003f 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 00043 74 1e je SHORT $LN9@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00045 48 8b cf mov rcx, rdi 00048 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0004d 48 8b 87 c0 00 00 00 mov rax, QWORD PTR [rdi+192] 00054 0f b6 08 movzx ecx, BYTE PTR [rax] 00057 48 ff c0 inc rax 0005a 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax 00061 eb 02 jmp SHORT $LN7@stbi__hdr_ $LN9@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00063 32 c9 xor cl, cl $LN7@stbi__hdr_: ; 6656 : if (stbi__get8(s) != signature[i]) 00065 0f be 03 movsx eax, BYTE PTR [rbx] 00068 0f b6 c9 movzx ecx, cl 0006b 3b c8 cmp ecx, eax 0006d 75 39 jne SHORT $LN14@stbi__hdr_ ; 6654 : int i; ; 6655 : for (i = 0; signature[i]; ++i) 0006f 48 ff c3 inc rbx 00072 80 3b 00 cmp BYTE PTR [rbx], 0 00075 75 a9 jne SHORT $LL4@stbi__hdr_ $LN18@stbi__hdr_: ; 342 : s->img_buffer = s->img_buffer_original; 00077 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] 0007e 48 89 87 c0 00 00 00 mov QWORD PTR [rdi+192], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00085 48 8b 87 d8 00 00 00 mov rax, QWORD PTR [rdi+216] 0008c 48 89 87 c8 00 00 00 mov QWORD PTR [rdi+200], rax ; 6657 : return 0; ; 6658 : stbi__rewind(s); ; 6659 : return 1; 00093 b8 01 00 00 00 mov eax, 1 ; 6660 : } 00098 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0009d 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 000a2 48 83 c4 20 add rsp, 32 ; 00000020H 000a6 5f pop rdi 000a7 c3 ret 0 $LN14@stbi__hdr_: 000a8 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000ad 33 c0 xor eax, eax 000af 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 000b4 48 83 c4 20 add rsp, 32 ; 00000020H 000b8 5f pop rdi 000b9 c3 ret 0 stbi__hdr_test_core ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_test _TEXT SEGMENT s$ = 48 stbi__hdr_test PROC ; COMDAT ; 6663 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 48 89 7c 24 18 mov QWORD PTR [rsp+24], rdi 0000f 41 56 push r14 00011 48 83 ec 20 sub rsp, 32 ; 00000020H 00015 48 8b f9 mov rdi, rcx 00018 48 8d 99 c0 00 00 00 lea rbx, QWORD PTR [rcx+192] 0001f 48 8d 35 00 00 00 00 lea rsi, OFFSET FLAT:??_C@_0M@HOIDFNFN@?$CD?$DPRADIANCE?6@ 00026 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL7@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00030 48 8b 03 mov rax, QWORD PTR [rbx] 00033 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 0003a 73 0b jae SHORT $LN11@stbi__hdr_ ; 1078 : return *s->img_buffer++; 0003c 0f b6 08 movzx ecx, BYTE PTR [rax] 0003f 48 ff c0 inc rax 00042 48 89 03 mov QWORD PTR [rbx], rax 00045 eb 1e jmp SHORT $LN10@stbi__hdr_ $LN11@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 00047 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 0004b 74 16 je SHORT $LN12@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 0004d 48 8b cf mov rcx, rdi 00050 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00055 48 8b 03 mov rax, QWORD PTR [rbx] 00058 0f b6 08 movzx ecx, BYTE PTR [rax] 0005b 48 ff c0 inc rax 0005e 48 89 03 mov QWORD PTR [rbx], rax 00061 eb 02 jmp SHORT $LN10@stbi__hdr_ $LN12@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00063 32 c9 xor cl, cl $LN10@stbi__hdr_: ; 6656 : if (stbi__get8(s) != signature[i]) 00065 0f be 06 movsx eax, BYTE PTR [rsi] 00068 0f b6 c9 movzx ecx, cl 0006b 3b c8 cmp ecx, eax 0006d 75 0f jne SHORT $LN34@stbi__hdr_ ; 1084 : } ; 1085 : ; 1086 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1087 : // nothing ; 1088 : #else ; 1089 : stbi_inline static int stbi__at_eof(stbi__context* s) ; 1090 : { ; 1091 : if (s->io.read) { ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) ; 5935 : dest[i] = src[i]; ; 5936 : } ; 5937 : ; 5938 : static stbi_uc* stbi__pic_load_core(stbi__context* s, int width, int height, int* comp, stbi_uc* result) ; 5939 : { ; 5940 : int act_comp = 0, num_packets = 0, y, chained; ; 5941 : stbi__pic_packet packets[10]; ; 5942 : ; 5943 : // this will (should...) cater for even some bizarre stuff like having data ; 5944 : // for the same channel in multiple packets. ; 5945 : do { ; 5946 : stbi__pic_packet* packet; ; 5947 : ; 5948 : if (num_packets == sizeof(packets) / sizeof(packets[0])) ; 5949 : return stbi__errpuc("bad format", "too many packets"); ; 5950 : ; 5951 : packet = &packets[num_packets++]; ; 5952 : ; 5953 : chained = stbi__get8(s); ; 5954 : packet->size = stbi__get8(s); ; 5955 : packet->type = stbi__get8(s); ; 5956 : packet->channel = stbi__get8(s); ; 5957 : ; 5958 : act_comp |= packet->channel; ; 5959 : ; 5960 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (reading packets)"); ; 5961 : if (packet->size != 8) return stbi__errpuc("bad format", "packet isn't 8bpp"); ; 5962 : } while (chained); ; 5963 : ; 5964 : *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? ; 5965 : ; 5966 : for (y = 0; y < height; ++y) { ; 5967 : int packet_idx; ; 5968 : ; 5969 : for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) { ; 5970 : stbi__pic_packet* packet = &packets[packet_idx]; ; 5971 : stbi_uc* dest = result + y * width * 4; ; 5972 : ; 5973 : switch (packet->type) { ; 5974 : default: ; 5975 : return stbi__errpuc("bad format", "packet has bad compression type"); ; 5976 : ; 5977 : case 0: {//uncompressed ; 5978 : int x; ; 5979 : ; 5980 : for (x = 0; x < width; ++x, dest += 4) ; 5981 : if (!stbi__readval(s, packet->channel, dest)) ; 5982 : return 0; ; 5983 : break; ; 5984 : } ; 5985 : ; 5986 : case 1://Pure RLE ; 5987 : { ; 5988 : int left = width, i; ; 5989 : ; 5990 : while (left > 0) { ; 5991 : stbi_uc count, value[4]; ; 5992 : ; 5993 : count = stbi__get8(s); ; 5994 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pure read count)"); ; 5995 : ; 5996 : if (count > left) ; 5997 : count = (stbi_uc)left; ; 5998 : ; 5999 : if (!stbi__readval(s, packet->channel, value)) return 0; ; 6000 : ; 6001 : for (i = 0; i < count; ++i, dest += 4) ; 6002 : stbi__copyval(packet->channel, dest, value); ; 6003 : left -= count; ; 6004 : } ; 6005 : } ; 6006 : break; ; 6007 : ; 6008 : case 2: {//Mixed RLE ; 6009 : int left = width; ; 6010 : while (left > 0) { ; 6011 : int count = stbi__get8(s), i; ; 6012 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (mixed read count)"); ; 6013 : ; 6014 : if (count >= 128) { // Repeated ; 6015 : stbi_uc value[4]; ; 6016 : ; 6017 : if (count == 128) ; 6018 : count = stbi__get16be(s); ; 6019 : else ; 6020 : count -= 127; ; 6021 : if (count > left) ; 6022 : return stbi__errpuc("bad file", "scanline overrun"); ; 6023 : ; 6024 : if (!stbi__readval(s, packet->channel, value)) ; 6025 : return 0; ; 6026 : ; 6027 : for (i = 0; i < count; ++i, dest += 4) ; 6028 : stbi__copyval(packet->channel, dest, value); ; 6029 : } ; 6030 : else { // Raw ; 6031 : ++count; ; 6032 : if (count > left) return stbi__errpuc("bad file", "scanline overrun"); ; 6033 : ; 6034 : for (i = 0; i < count; ++i, dest += 4) ; 6035 : if (!stbi__readval(s, packet->channel, dest)) ; 6036 : return 0; ; 6037 : } ; 6038 : left -= count; ; 6039 : } ; 6040 : break; ; 6041 : } ; 6042 : } ; 6043 : } ; 6044 : } ; 6045 : ; 6046 : return result; ; 6047 : } ; 6048 : ; 6049 : static void* stbi__pic_load(stbi__context* s, int* px, int* py, int* comp, int req_comp, stbi__result_info* ri) ; 6050 : { ; 6051 : stbi_uc* result; ; 6052 : int i, x, y, internal_comp; ; 6053 : STBI_NOTUSED(ri); ; 6054 : ; 6055 : if (!comp) comp = &internal_comp; ; 6056 : ; 6057 : for (i = 0; i < 92; ++i) ; 6058 : stbi__get8(s); ; 6059 : ; 6060 : x = stbi__get16be(s); ; 6061 : y = stbi__get16be(s); ; 6062 : ; 6063 : if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 6064 : if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 6065 : ; 6066 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); ; 6067 : if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); ; 6068 : ; 6069 : stbi__get32be(s); //skip `ratio' ; 6070 : stbi__get16be(s); //skip `fields' ; 6071 : stbi__get16be(s); //skip `pad' ; 6072 : ; 6073 : // intermediate buffer is RGBA ; 6074 : result = (stbi_uc*)stbi__malloc_mad3(x, y, 4, 0); ; 6075 : if (!result) return stbi__errpuc("outofmem", "Out of memory"); ; 6076 : memset(result, 0xff, x * y * 4); ; 6077 : ; 6078 : if (!stbi__pic_load_core(s, x, y, comp, result)) { ; 6079 : STBI_FREE(result); ; 6080 : result = 0; ; 6081 : } ; 6082 : *px = x; ; 6083 : *py = y; ; 6084 : if (req_comp == 0) req_comp = *comp; ; 6085 : result = stbi__convert_format(result, 4, req_comp, x, y); ; 6086 : ; 6087 : return result; ; 6088 : } ; 6089 : ; 6090 : static int stbi__pic_test(stbi__context* s) ; 6091 : { ; 6092 : int r = stbi__pic_test_core(s); ; 6093 : stbi__rewind(s); ; 6094 : return r; ; 6095 : } ; 6096 : #endif ; 6097 : ; 6098 : // ************************************************************************************************* ; 6099 : // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb ; 6100 : ; 6101 : #ifndef STBI_NO_GIF ; 6102 : typedef struct ; 6103 : { ; 6104 : stbi__int16 prefix; ; 6105 : stbi_uc first; ; 6106 : stbi_uc suffix; ; 6107 : } stbi__gif_lzw; ; 6108 : ; 6109 : typedef struct ; 6110 : { ; 6111 : int w, h; ; 6112 : stbi_uc* out; // output buffer (always 4 components) ; 6113 : stbi_uc* background; // The current "background" as far as a gif is concerned ; 6114 : stbi_uc* history; ; 6115 : int flags, bgindex, ratio, transparent, eflags; ; 6116 : stbi_uc pal[256][4]; ; 6117 : stbi_uc lpal[256][4]; ; 6118 : stbi__gif_lzw codes[8192]; ; 6119 : stbi_uc* color_table; ; 6120 : int parse, step; ; 6121 : int lflags; ; 6122 : int start_x, start_y; ; 6123 : int max_x, max_y; ; 6124 : int cur_x, cur_y; ; 6125 : int line_size; ; 6126 : int delay; ; 6127 : } stbi__gif; ; 6128 : ; 6129 : static int stbi__gif_test_raw(stbi__context* s) ; 6130 : { ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; ; 6133 : sz = stbi__get8(s); ; 6134 : if (sz != '9' && sz != '7') return 0; ; 6135 : if (stbi__get8(s) != 'a') return 0; ; 6136 : return 1; ; 6137 : } ; 6138 : ; 6139 : static int stbi__gif_test(stbi__context* s) ; 6140 : { ; 6141 : int r = stbi__gif_test_raw(s); ; 6142 : stbi__rewind(s); ; 6143 : return r; ; 6144 : } ; 6145 : ; 6146 : static void stbi__gif_parse_colortable(stbi__context* s, stbi_uc pal[256][4], int num_entries, int transp) ; 6147 : { ; 6148 : int i; ; 6149 : for (i = 0; i < num_entries; ++i) { ; 6150 : pal[i][2] = stbi__get8(s); ; 6151 : pal[i][1] = stbi__get8(s); ; 6152 : pal[i][0] = stbi__get8(s); ; 6153 : pal[i][3] = transp == i ? 0 : 255; ; 6154 : } ; 6155 : } ; 6156 : ; 6157 : static int stbi__gif_header(stbi__context* s, stbi__gif* g, int* comp, int is_info) ; 6158 : { ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') ; 6161 : return stbi__err("not GIF", "Corrupt GIF"); ; 6162 : ; 6163 : version = stbi__get8(s); ; 6164 : if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); ; 6165 : if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); ; 6166 : ; 6167 : stbi__g_failure_reason = ""; ; 6168 : g->w = stbi__get16le(s); ; 6169 : g->h = stbi__get16le(s); ; 6170 : g->flags = stbi__get8(s); ; 6171 : g->bgindex = stbi__get8(s); ; 6172 : g->ratio = stbi__get8(s); ; 6173 : g->transparent = -1; ; 6174 : ; 6175 : if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 6176 : if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 6177 : ; 6178 : if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments ; 6179 : ; 6180 : if (is_info) return 1; ; 6181 : ; 6182 : if (g->flags & 0x80) ; 6183 : stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); ; 6184 : ; 6185 : return 1; ; 6186 : } ; 6187 : ; 6188 : static int stbi__gif_info_raw(stbi__context* s, int* x, int* y, int* comp) ; 6189 : { ; 6190 : stbi__gif* g = (stbi__gif*)stbi__malloc(sizeof(stbi__gif)); ; 6191 : if (!g) return stbi__err("outofmem", "Out of memory"); ; 6192 : if (!stbi__gif_header(s, g, comp, 1)) { ; 6193 : STBI_FREE(g); ; 6194 : stbi__rewind(s); ; 6195 : return 0; ; 6196 : } ; 6197 : if (x) *x = g->w; ; 6198 : if (y) *y = g->h; ; 6199 : STBI_FREE(g); ; 6200 : return 1; ; 6201 : } ; 6202 : ; 6203 : static void stbi__out_gif_code(stbi__gif* g, stbi__uint16 code) ; 6204 : { ; 6205 : stbi_uc* p, * c; ; 6206 : int idx; ; 6207 : ; 6208 : // recurse to decode the prefixes, since the linked-list is backwards, ; 6209 : // and working backwards through an interleaved image would be nasty ; 6210 : if (g->codes[code].prefix >= 0) ; 6211 : stbi__out_gif_code(g, g->codes[code].prefix); ; 6212 : ; 6213 : if (g->cur_y >= g->max_y) return; ; 6214 : ; 6215 : idx = g->cur_x + g->cur_y; ; 6216 : p = &g->out[idx]; ; 6217 : g->history[idx / 4] = 1; ; 6218 : ; 6219 : c = &g->color_table[g->codes[code].suffix * 4]; ; 6220 : if (c[3] > 128) { // don't render transparent pixels; ; 6221 : p[0] = c[2]; ; 6222 : p[1] = c[1]; ; 6223 : p[2] = c[0]; ; 6224 : p[3] = c[3]; ; 6225 : } ; 6226 : g->cur_x += 4; ; 6227 : ; 6228 : if (g->cur_x >= g->max_x) { ; 6229 : g->cur_x = g->start_x; ; 6230 : g->cur_y += g->step; ; 6231 : ; 6232 : while (g->cur_y >= g->max_y && g->parse > 0) { ; 6233 : g->step = (1 << g->parse) * g->line_size; ; 6234 : g->cur_y = g->start_y + (g->step >> 1); ; 6235 : --g->parse; ; 6236 : } ; 6237 : } ; 6238 : } ; 6239 : ; 6240 : static stbi_uc* stbi__process_gif_raster(stbi__context* s, stbi__gif* g) ; 6241 : { ; 6242 : stbi_uc lzw_cs; ; 6243 : stbi__int32 len, init_code; ; 6244 : stbi__uint32 first; ; 6245 : stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; ; 6246 : stbi__gif_lzw* p; ; 6247 : ; 6248 : lzw_cs = stbi__get8(s); ; 6249 : if (lzw_cs > 12) return NULL; ; 6250 : clear = 1 << lzw_cs; ; 6251 : first = 1; ; 6252 : codesize = lzw_cs + 1; ; 6253 : codemask = (1 << codesize) - 1; ; 6254 : bits = 0; ; 6255 : valid_bits = 0; ; 6256 : for (init_code = 0; init_code < clear; init_code++) { ; 6257 : g->codes[init_code].prefix = -1; ; 6258 : g->codes[init_code].first = (stbi_uc)init_code; ; 6259 : g->codes[init_code].suffix = (stbi_uc)init_code; ; 6260 : } ; 6261 : ; 6262 : // support no starting clear code ; 6263 : avail = clear + 2; ; 6264 : oldcode = -1; ; 6265 : ; 6266 : len = 0; ; 6267 : for (;;) { ; 6268 : if (valid_bits < codesize) { ; 6269 : if (len == 0) { ; 6270 : len = stbi__get8(s); // start new block ; 6271 : if (len == 0) ; 6272 : return g->out; ; 6273 : } ; 6274 : --len; ; 6275 : bits |= (stbi__int32)stbi__get8(s) << valid_bits; ; 6276 : valid_bits += 8; ; 6277 : } ; 6278 : else { ; 6279 : stbi__int32 code = bits & codemask; ; 6280 : bits >>= codesize; ; 6281 : valid_bits -= codesize; ; 6282 : // @OPTIMIZE: is there some way we can accelerate the non-clear path? ; 6283 : if (code == clear) { // clear code ; 6284 : codesize = lzw_cs + 1; ; 6285 : codemask = (1 << codesize) - 1; ; 6286 : avail = clear + 2; ; 6287 : oldcode = -1; ; 6288 : first = 0; ; 6289 : } ; 6290 : else if (code == clear + 1) { // end of stream code ; 6291 : stbi__skip(s, len); ; 6292 : while ((len = stbi__get8(s)) > 0) ; 6293 : stbi__skip(s, len); ; 6294 : return g->out; ; 6295 : } ; 6296 : else if (code <= avail) { ; 6297 : if (first) { ; 6298 : return stbi__errpuc("no clear code", "Corrupt GIF"); ; 6299 : } ; 6300 : ; 6301 : if (oldcode >= 0) { ; 6302 : p = &g->codes[avail++]; ; 6303 : if (avail > 8192) { ; 6304 : return stbi__errpuc("too many codes", "Corrupt GIF"); ; 6305 : } ; 6306 : ; 6307 : p->prefix = (stbi__int16)oldcode; ; 6308 : p->first = g->codes[oldcode].first; ; 6309 : p->suffix = (code == avail) ? p->first : g->codes[code].first; ; 6310 : } ; 6311 : else if (code == avail) ; 6312 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); ; 6313 : ; 6314 : stbi__out_gif_code(g, (stbi__uint16)code); ; 6315 : ; 6316 : if ((avail & codemask) == 0 && avail <= 0x0FFF) { ; 6317 : codesize++; ; 6318 : codemask = (1 << codesize) - 1; ; 6319 : } ; 6320 : ; 6321 : oldcode = code; ; 6322 : } ; 6323 : else { ; 6324 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); ; 6325 : } ; 6326 : } ; 6327 : } ; 6328 : } ; 6329 : ; 6330 : // this function is designed to support animated gifs, although stb_image doesn't support it ; 6331 : // two back is the image from two frames ago, used for a very specific disposal format ; 6332 : static stbi_uc* stbi__gif_load_next(stbi__context* s, stbi__gif* g, int* comp, int req_comp, stbi_uc* two_back) ; 6333 : { ; 6334 : int dispose; ; 6335 : int first_frame; ; 6336 : int pi; ; 6337 : int pcount; ; 6338 : STBI_NOTUSED(req_comp); ; 6339 : ; 6340 : // on first frame, any non-written pixels get the background colour (non-transparent) ; 6341 : first_frame = 0; ; 6342 : if (g->out == 0) { ; 6343 : if (!stbi__gif_header(s, g, comp, 0)) return 0; // stbi__g_failure_reason set by stbi__gif_header ; 6344 : if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) ; 6345 : return stbi__errpuc("too large", "GIF image is too large"); ; 6346 : pcount = g->w * g->h; ; 6347 : g->out = (stbi_uc*)stbi__malloc(4 * pcount); ; 6348 : g->background = (stbi_uc*)stbi__malloc(4 * pcount); ; 6349 : g->history = (stbi_uc*)stbi__malloc(pcount); ; 6350 : if (!g->out || !g->background || !g->history) ; 6351 : return stbi__errpuc("outofmem", "Out of memory"); ; 6352 : ; 6353 : // image is treated as "transparent" at the start - ie, nothing overwrites the current background; ; 6354 : // background colour is only used for pixels that are not rendered first frame, after that "background" ; 6355 : // color refers to the color that was there the previous frame. ; 6356 : memset(g->out, 0x00, 4 * pcount); ; 6357 : memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) ; 6358 : memset(g->history, 0x00, pcount); // pixels that were affected previous frame ; 6359 : first_frame = 1; ; 6360 : } ; 6361 : else { ; 6362 : // second frame - how do we dispose of the previous one? ; 6363 : dispose = (g->eflags & 0x1C) >> 2; ; 6364 : pcount = g->w * g->h; ; 6365 : ; 6366 : if ((dispose == 3) && (two_back == 0)) { ; 6367 : dispose = 2; // if I don't have an image to revert back to, default to the old background ; 6368 : } ; 6369 : ; 6370 : if (dispose == 3) { // use previous graphic ; 6371 : for (pi = 0; pi < pcount; ++pi) { ; 6372 : if (g->history[pi]) { ; 6373 : memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); ; 6374 : } ; 6375 : } ; 6376 : } ; 6377 : else if (dispose == 2) { ; 6378 : // restore what was changed last frame to background before that frame; ; 6379 : for (pi = 0; pi < pcount; ++pi) { ; 6380 : if (g->history[pi]) { ; 6381 : memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); ; 6382 : } ; 6383 : } ; 6384 : } ; 6385 : else { ; 6386 : // This is a non-disposal case eithe way, so just ; 6387 : // leave the pixels as is, and they will become the new background ; 6388 : // 1: do not dispose ; 6389 : // 0: not specified. ; 6390 : } ; 6391 : ; 6392 : // background is what out is after the undoing of the previou frame; ; 6393 : memcpy(g->background, g->out, 4 * g->w * g->h); ; 6394 : } ; 6395 : ; 6396 : // clear my history; ; 6397 : memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame ; 6398 : ; 6399 : for (;;) { ; 6400 : int tag = stbi__get8(s); ; 6401 : switch (tag) { ; 6402 : case 0x2C: /* Image Descriptor */ ; 6403 : { ; 6404 : stbi__int32 x, y, w, h; ; 6405 : stbi_uc* o; ; 6406 : ; 6407 : x = stbi__get16le(s); ; 6408 : y = stbi__get16le(s); ; 6409 : w = stbi__get16le(s); ; 6410 : h = stbi__get16le(s); ; 6411 : if (((x + w) > (g->w)) || ((y + h) > (g->h))) ; 6412 : return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); ; 6413 : ; 6414 : g->line_size = g->w * 4; ; 6415 : g->start_x = x * 4; ; 6416 : g->start_y = y * g->line_size; ; 6417 : g->max_x = g->start_x + w * 4; ; 6418 : g->max_y = g->start_y + h * g->line_size; ; 6419 : g->cur_x = g->start_x; ; 6420 : g->cur_y = g->start_y; ; 6421 : ; 6422 : // if the width of the specified rectangle is 0, that means ; 6423 : // we may not see *any* pixels or the image is malformed; ; 6424 : // to make sure this is caught, move the current y down to ; 6425 : // max_y (which is what out_gif_code checks). ; 6426 : if (w == 0) ; 6427 : g->cur_y = g->max_y; ; 6428 : ; 6429 : g->lflags = stbi__get8(s); ; 6430 : ; 6431 : if (g->lflags & 0x40) { ; 6432 : g->step = 8 * g->line_size; // first interlaced spacing ; 6433 : g->parse = 3; ; 6434 : } ; 6435 : else { ; 6436 : g->step = g->line_size; ; 6437 : g->parse = 0; ; 6438 : } ; 6439 : ; 6440 : if (g->lflags & 0x80) { ; 6441 : stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); ; 6442 : g->color_table = (stbi_uc*)g->lpal; ; 6443 : } ; 6444 : else if (g->flags & 0x80) { ; 6445 : g->color_table = (stbi_uc*)g->pal; ; 6446 : } ; 6447 : else ; 6448 : return stbi__errpuc("missing color table", "Corrupt GIF"); ; 6449 : ; 6450 : o = stbi__process_gif_raster(s, g); ; 6451 : if (!o) return NULL; ; 6452 : ; 6453 : // if this was the first frame, ; 6454 : pcount = g->w * g->h; ; 6455 : if (first_frame && (g->bgindex > 0)) { ; 6456 : // if first frame, any pixel not drawn to gets the background color ; 6457 : for (pi = 0; pi < pcount; ++pi) { ; 6458 : if (g->history[pi] == 0) { ; 6459 : g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; ; 6460 : memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); ; 6461 : } ; 6462 : } ; 6463 : } ; 6464 : ; 6465 : return o; ; 6466 : } ; 6467 : ; 6468 : case 0x21: // Comment Extension. ; 6469 : { ; 6470 : int len; ; 6471 : int ext = stbi__get8(s); ; 6472 : if (ext == 0xF9) { // Graphic Control Extension. ; 6473 : len = stbi__get8(s); ; 6474 : if (len == 4) { ; 6475 : g->eflags = stbi__get8(s); ; 6476 : g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. ; 6477 : ; 6478 : // unset old transparent ; 6479 : if (g->transparent >= 0) { ; 6480 : g->pal[g->transparent][3] = 255; ; 6481 : } ; 6482 : if (g->eflags & 0x01) { ; 6483 : g->transparent = stbi__get8(s); ; 6484 : if (g->transparent >= 0) { ; 6485 : g->pal[g->transparent][3] = 0; ; 6486 : } ; 6487 : } ; 6488 : else { ; 6489 : // don't need transparent ; 6490 : stbi__skip(s, 1); ; 6491 : g->transparent = -1; ; 6492 : } ; 6493 : } ; 6494 : else { ; 6495 : stbi__skip(s, len); ; 6496 : break; ; 6497 : } ; 6498 : } ; 6499 : while ((len = stbi__get8(s)) != 0) { ; 6500 : stbi__skip(s, len); ; 6501 : } ; 6502 : break; ; 6503 : } ; 6504 : ; 6505 : case 0x3B: // gif stream termination code ; 6506 : return (stbi_uc*)s; // using '1' causes warning on some compilers ; 6507 : ; 6508 : default: ; 6509 : return stbi__errpuc("unknown code", "Corrupt GIF"); ; 6510 : } ; 6511 : } ; 6512 : } ; 6513 : ; 6514 : static void* stbi__load_gif_main_outofmem(stbi__gif* g, stbi_uc* out, int** delays) ; 6515 : { ; 6516 : STBI_FREE(g->out); ; 6517 : STBI_FREE(g->history); ; 6518 : STBI_FREE(g->background); ; 6519 : ; 6520 : if (out) STBI_FREE(out); ; 6521 : if (delays && *delays) STBI_FREE(*delays); ; 6522 : return stbi__errpuc("outofmem", "Out of memory"); ; 6523 : } ; 6524 : ; 6525 : static void* stbi__load_gif_main(stbi__context* s, int** delays, int* x, int* y, int* z, int* comp, int req_comp) ; 6526 : { ; 6527 : if (stbi__gif_test(s)) { ; 6528 : int layers = 0; ; 6529 : stbi_uc* u = 0; ; 6530 : stbi_uc* out = 0; ; 6531 : stbi_uc* two_back = 0; ; 6532 : stbi__gif g; ; 6533 : int stride; ; 6534 : int out_size = 0; ; 6535 : int delays_size = 0; ; 6536 : ; 6537 : STBI_NOTUSED(out_size); ; 6538 : STBI_NOTUSED(delays_size); ; 6539 : ; 6540 : memset(&g, 0, sizeof(g)); ; 6541 : if (delays) { ; 6542 : *delays = 0; ; 6543 : } ; 6544 : ; 6545 : do { ; 6546 : u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); ; 6547 : if (u == (stbi_uc*)s) u = 0; // end of animated gif marker ; 6548 : ; 6549 : if (u) { ; 6550 : *x = g.w; ; 6551 : *y = g.h; ; 6552 : ++layers; ; 6553 : stride = g.w * g.h * 4; ; 6554 : ; 6555 : if (out) { ; 6556 : void* tmp = (stbi_uc*)STBI_REALLOC_SIZED(out, out_size, layers * stride); ; 6557 : if (!tmp) ; 6558 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6559 : else { ; 6560 : out = (stbi_uc*)tmp; ; 6561 : out_size = layers * stride; ; 6562 : } ; 6563 : ; 6564 : if (delays) { ; 6565 : int* new_delays = (int*)STBI_REALLOC_SIZED(*delays, delays_size, sizeof(int) * layers); ; 6566 : if (!new_delays) ; 6567 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6568 : *delays = new_delays; ; 6569 : delays_size = layers * sizeof(int); ; 6570 : } ; 6571 : } ; 6572 : else { ; 6573 : out = (stbi_uc*)stbi__malloc(layers * stride); ; 6574 : if (!out) ; 6575 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6576 : out_size = layers * stride; ; 6577 : if (delays) { ; 6578 : *delays = (int*)stbi__malloc(layers * sizeof(int)); ; 6579 : if (!*delays) ; 6580 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6581 : delays_size = layers * sizeof(int); ; 6582 : } ; 6583 : } ; 6584 : memcpy(out + ((layers - 1) * stride), u, stride); ; 6585 : if (layers >= 2) { ; 6586 : two_back = out - 2 * stride; ; 6587 : } ; 6588 : ; 6589 : if (delays) { ; 6590 : (*delays)[layers - 1U] = g.delay; ; 6591 : } ; 6592 : } ; 6593 : } while (u != 0); ; 6594 : ; 6595 : // free temp buffer; ; 6596 : STBI_FREE(g.out); ; 6597 : STBI_FREE(g.history); ; 6598 : STBI_FREE(g.background); ; 6599 : ; 6600 : // do the final conversion after loading everything; ; 6601 : if (req_comp && req_comp != 4) ; 6602 : out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); ; 6603 : ; 6604 : *z = layers; ; 6605 : return out; ; 6606 : } ; 6607 : else { ; 6608 : return stbi__errpuc("not GIF", "Image was not as a gif type."); ; 6609 : } ; 6610 : } ; 6611 : ; 6612 : static void* stbi__gif_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 6613 : { ; 6614 : stbi_uc* u = 0; ; 6615 : stbi__gif g; ; 6616 : memset(&g, 0, sizeof(g)); ; 6617 : STBI_NOTUSED(ri); ; 6618 : ; 6619 : u = stbi__gif_load_next(s, &g, comp, req_comp, 0); ; 6620 : if (u == (stbi_uc*)s) u = 0; // end of animated gif marker ; 6621 : if (u) { ; 6622 : *x = g.w; ; 6623 : *y = g.h; ; 6624 : ; 6625 : // moved conversion to after successful load so that the same ; 6626 : // can be done for multiple frames. ; 6627 : if (req_comp && req_comp != 4) ; 6628 : u = stbi__convert_format(u, 4, req_comp, g.w, g.h); ; 6629 : } ; 6630 : else if (g.out) { ; 6631 : // if there was an error and we allocated an image buffer, free it! ; 6632 : STBI_FREE(g.out); ; 6633 : } ; 6634 : ; 6635 : // free buffers needed for multiple frame loading; ; 6636 : STBI_FREE(g.history); ; 6637 : STBI_FREE(g.background); ; 6638 : ; 6639 : return u; ; 6640 : } ; 6641 : ; 6642 : static int stbi__gif_info(stbi__context* s, int* x, int* y, int* comp) ; 6643 : { ; 6644 : return stbi__gif_info_raw(s, x, y, comp); ; 6645 : } ; 6646 : #endif ; 6647 : ; 6648 : // ************************************************************************************************* ; 6649 : // Radiance RGBE HDR loader ; 6650 : // originally by Nicolas Schulz ; 6651 : #ifndef STBI_NO_HDR ; 6652 : static int stbi__hdr_test_core(stbi__context* s, const char* signature) ; 6653 : { ; 6654 : int i; ; 6655 : for (i = 0; signature[i]; ++i) 0006f 48 ff c6 inc rsi 00072 80 3e 00 cmp BYTE PTR [rsi], 0 00075 75 b9 jne SHORT $LL7@stbi__hdr_ ; 6658 : stbi__rewind(s); ; 6659 : return 1; 00077 b8 01 00 00 00 mov eax, 1 0007c eb 6f jmp SHORT $LN18@stbi__hdr_ $LN34@stbi__hdr_: ; 6657 : return 0; 0007e 48 8b 87 d0 00 00 00 mov rax, QWORD PTR [rdi+208] 00085 48 8d 35 00 00 00 00 lea rsi, OFFSET FLAT:??_C@_07KFDJIKCK@?$CD?$DPRGBE?6@ 0008c 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] 00093 48 89 03 mov QWORD PTR [rbx], rax 00096 48 89 8f c8 00 00 00 mov QWORD PTR [rdi+200], rcx 0009d 0f 1f 00 npad 3 $LL21@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 000a0 48 3b 87 c8 00 00 00 cmp rax, QWORD PTR [rdi+200] 000a7 73 0b jae SHORT $LN25@stbi__hdr_ ; 1078 : return *s->img_buffer++; 000a9 0f b6 08 movzx ecx, BYTE PTR [rax] 000ac 48 ff c0 inc rax 000af 48 89 03 mov QWORD PTR [rbx], rax 000b2 eb 1e jmp SHORT $LN24@stbi__hdr_ $LN25@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 000b4 83 7f 30 00 cmp DWORD PTR [rdi+48], 0 000b8 74 16 je SHORT $LN26@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 000ba 48 8b cf mov rcx, rdi 000bd e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000c2 48 8b 03 mov rax, QWORD PTR [rbx] 000c5 0f b6 08 movzx ecx, BYTE PTR [rax] 000c8 48 ff c0 inc rax 000cb 48 89 03 mov QWORD PTR [rbx], rax 000ce eb 02 jmp SHORT $LN24@stbi__hdr_ $LN26@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 000d0 32 c9 xor cl, cl $LN24@stbi__hdr_: ; 6656 : if (stbi__get8(s) != signature[i]) 000d2 0f b6 d1 movzx edx, cl 000d5 0f be 0e movsx ecx, BYTE PTR [rsi] 000d8 3b d1 cmp edx, ecx 000da 75 0f jne SHORT $LN35@stbi__hdr_ ; 1084 : } ; 1085 : ; 1086 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1087 : // nothing ; 1088 : #else ; 1089 : stbi_inline static int stbi__at_eof(stbi__context* s) ; 1090 : { ; 1091 : if (s->io.read) { ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; ; 1096 : } ; 1097 : ; 1098 : return s->img_buffer >= s->img_buffer_end; ; 1099 : } ; 1100 : #endif ; 1101 : ; 1102 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) ; 1103 : // nothing ; 1104 : #else ; 1105 : static void stbi__skip(stbi__context* s, int n) ; 1106 : { ; 1107 : if (n == 0) return; // already there! ; 1108 : if (n < 0) { ; 1109 : s->img_buffer = s->img_buffer_end; ; 1110 : return; ; 1111 : } ; 1112 : if (s->io.read) { ; 1113 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1114 : if (blen < n) { ; 1115 : s->img_buffer = s->img_buffer_end; ; 1116 : (s->io.skip)(s->io_user_data, n - blen); ; 1117 : return; ; 1118 : } ; 1119 : } ; 1120 : s->img_buffer += n; ; 1121 : } ; 1122 : #endif ; 1123 : ; 1124 : #if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) ; 1125 : // nothing ; 1126 : #else ; 1127 : static int stbi__getn(stbi__context* s, stbi_uc* buffer, int n) ; 1128 : { ; 1129 : if (s->io.read) { ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); ; 1131 : if (blen < n) { ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; ; 1139 : return res; ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { ; 1144 : memcpy(buffer, s->img_buffer, n); ; 1145 : s->img_buffer += n; ; 1146 : return 1; ; 1147 : } ; 1148 : else ; 1149 : return 0; ; 1150 : } ; 1151 : #endif ; 1152 : ; 1153 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1154 : // nothing ; 1155 : #else ; 1156 : static int stbi__get16be(stbi__context* s) ; 1157 : { ; 1158 : int z = stbi__get8(s); ; 1159 : return (z << 8) + stbi__get8(s); ; 1160 : } ; 1161 : #endif ; 1162 : ; 1163 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) ; 1164 : // nothing ; 1165 : #else ; 1166 : static stbi__uint32 stbi__get32be(stbi__context* s) ; 1167 : { ; 1168 : stbi__uint32 z = stbi__get16be(s); ; 1169 : return (z << 16) + stbi__get16be(s); ; 1170 : } ; 1171 : #endif ; 1172 : ; 1173 : #if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) ; 1174 : // nothing ; 1175 : #else ; 1176 : static int stbi__get16le(stbi__context* s) ; 1177 : { ; 1178 : int z = stbi__get8(s); ; 1179 : return z + (stbi__get8(s) << 8); ; 1180 : } ; 1181 : #endif ; 1182 : ; 1183 : #ifndef STBI_NO_BMP ; 1184 : static stbi__uint32 stbi__get32le(stbi__context* s) ; 1185 : { ; 1186 : stbi__uint32 z = stbi__get16le(s); ; 1187 : z += (stbi__uint32)stbi__get16le(s) << 16; ; 1188 : return z; ; 1189 : } ; 1190 : #endif ; 1191 : ; 1192 : #define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings ; 1193 : ; 1194 : #if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1195 : // nothing ; 1196 : #else ; 1197 : ////////////////////////////////////////////////////////////////////////////// ; 1198 : // ; 1199 : // generic converter from built-in img_n to req_comp ; 1200 : // individual types do this automatically as much as possible (e.g. jpeg ; 1201 : // does all cases internally since it needs to colorspace convert anyway, ; 1202 : // and it never has alpha, so very few cases ). png can automatically ; 1203 : // interleave an alpha=255 channel, but falls back to this for other cases ; 1204 : // ; 1205 : // assume data buffer is malloced, so malloc a new one and free that one ; 1206 : // only failure mode is malloc failing ; 1207 : ; 1208 : static stbi_uc stbi__compute_y(int r, int g, int b) ; 1209 : { ; 1210 : return (stbi_uc)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1211 : } ; 1212 : #endif ; 1213 : ; 1214 : #if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) ; 1215 : // nothing ; 1216 : #else ; 1217 : static unsigned char* stbi__convert_format(unsigned char* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1218 : { ; 1219 : int i, j; ; 1220 : unsigned char* good; ; 1221 : ; 1222 : if (req_comp == img_n) return data; ; 1223 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1224 : ; 1225 : good = (unsigned char*)stbi__malloc_mad3(req_comp, x, y, 0); ; 1226 : if (good == NULL) { ; 1227 : STBI_FREE(data); ; 1228 : return stbi__errpuc("outofmem", "Out of memory"); ; 1229 : } ; 1230 : ; 1231 : for (j = 0; j < (int)y; ++j) { ; 1232 : unsigned char* src = data + j * x * img_n; ; 1233 : unsigned char* dest = good + j * x * req_comp; ; 1234 : ; 1235 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1236 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1237 : // convert source image with img_n components to one with req_comp components; ; 1238 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1239 : switch (STBI__COMBO(img_n, req_comp)) { ; 1240 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 255; } break; ; 1241 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1242 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 255; } break; ; 1243 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1244 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1245 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1246 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 255; } break; ; 1247 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1248 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = 255; } break; ; 1249 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); } break; ; 1250 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1251 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1252 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1253 : } ; 1254 : #undef STBI__CASE ; 1255 : } ; 1256 : ; 1257 : STBI_FREE(data); ; 1258 : return good; ; 1259 : } ; 1260 : #endif ; 1261 : ; 1262 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1263 : // nothing ; 1264 : #else ; 1265 : static stbi__uint16 stbi__compute_y_16(int r, int g, int b) ; 1266 : { ; 1267 : return (stbi__uint16)(((r * 77) + (g * 150) + (29 * b)) >> 8); ; 1268 : } ; 1269 : #endif ; 1270 : ; 1271 : #if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) ; 1272 : // nothing ; 1273 : #else ; 1274 : static stbi__uint16* stbi__convert_format16(stbi__uint16* data, int img_n, int req_comp, unsigned int x, unsigned int y) ; 1275 : { ; 1276 : int i, j; ; 1277 : stbi__uint16* good; ; 1278 : ; 1279 : if (req_comp == img_n) return data; ; 1280 : STBI_ASSERT(req_comp >= 1 && req_comp <= 4); ; 1281 : ; 1282 : good = (stbi__uint16*)stbi__malloc(req_comp * x * y * 2); ; 1283 : if (good == NULL) { ; 1284 : STBI_FREE(data); ; 1285 : return (stbi__uint16*)stbi__errpuc("outofmem", "Out of memory"); ; 1286 : } ; 1287 : ; 1288 : for (j = 0; j < (int)y; ++j) { ; 1289 : stbi__uint16* src = data + j * x * img_n; ; 1290 : stbi__uint16* dest = good + j * x * req_comp; ; 1291 : ; 1292 : #define STBI__COMBO(a,b) ((a)*8+(b)) ; 1293 : #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) ; 1294 : // convert source image with img_n components to one with req_comp components; ; 1295 : // avoid switch per pixel, so use switch per scanline and massive macros ; 1296 : switch (STBI__COMBO(img_n, req_comp)) { ; 1297 : STBI__CASE(1, 2) { dest[0] = src[0]; dest[1] = 0xffff; } break; ; 1298 : STBI__CASE(1, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1299 : STBI__CASE(1, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = 0xffff; } break; ; 1300 : STBI__CASE(2, 1) { dest[0] = src[0]; } break; ; 1301 : STBI__CASE(2, 3) { dest[0] = dest[1] = dest[2] = src[0]; } break; ; 1302 : STBI__CASE(2, 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } break; ; 1303 : STBI__CASE(3, 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = 0xffff; } break; ; 1304 : STBI__CASE(3, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1305 : STBI__CASE(3, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = 0xffff; } break; ; 1306 : STBI__CASE(4, 1) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); } break; ; 1307 : STBI__CASE(4, 2) { dest[0] = stbi__compute_y_16(src[0], src[1], src[2]); dest[1] = src[3]; } break; ; 1308 : STBI__CASE(4, 3) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } break; ; 1309 : default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*)stbi__errpuc("unsupported", "Unsupported format conversion"); ; 1310 : } ; 1311 : #undef STBI__CASE ; 1312 : } ; 1313 : ; 1314 : STBI_FREE(data); ; 1315 : return good; ; 1316 : } ; 1317 : #endif ; 1318 : ; 1319 : #ifndef STBI_NO_LINEAR ; 1320 : static float* stbi__ldr_to_hdr(stbi_uc* data, int x, int y, int comp) ; 1321 : { ; 1322 : int i, k, n; ; 1323 : float* output; ; 1324 : if (!data) return NULL; ; 1325 : output = (float*)stbi__malloc_mad4(x, y, comp, sizeof(float), 0); ; 1326 : if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } ; 1327 : // compute number of non-alpha components ; 1328 : if (comp & 1) n = comp; else n = comp - 1; ; 1329 : for (i = 0; i < x * y; ++i) { ; 1330 : for (k = 0; k < n; ++k) { ; 1331 : output[i * comp + k] = (float)(pow(data[i * comp + k] / 255.0f, stbi__l2h_gamma) * stbi__l2h_scale); ; 1332 : } ; 1333 : } ; 1334 : if (n < comp) { ; 1335 : for (i = 0; i < x * y; ++i) { ; 1336 : output[i * comp + n] = data[i * comp + n] / 255.0f; ; 1337 : } ; 1338 : } ; 1339 : STBI_FREE(data); ; 1340 : return output; ; 1341 : } ; 1342 : #endif ; 1343 : ; 1344 : #ifndef STBI_NO_HDR ; 1345 : #define stbi__float2int(x) ((int) (x)) ; 1346 : static stbi_uc* stbi__hdr_to_ldr(float* data, int x, int y, int comp) ; 1347 : { ; 1348 : int i, k, n; ; 1349 : stbi_uc* output; ; 1350 : if (!data) return NULL; ; 1351 : output = (stbi_uc*)stbi__malloc_mad3(x, y, comp, 0); ; 1352 : if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } ; 1353 : // compute number of non-alpha components ; 1354 : if (comp & 1) n = comp; else n = comp - 1; ; 1355 : for (i = 0; i < x * y; ++i) { ; 1356 : for (k = 0; k < n; ++k) { ; 1357 : float z = (float)pow(data[i * comp + k] * stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; ; 1358 : if (z < 0) z = 0; ; 1359 : if (z > 255) z = 255; ; 1360 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1361 : } ; 1362 : if (k < comp) { ; 1363 : float z = data[i * comp + k] * 255 + 0.5f; ; 1364 : if (z < 0) z = 0; ; 1365 : if (z > 255) z = 255; ; 1366 : output[i * comp + k] = (stbi_uc)stbi__float2int(z); ; 1367 : } ; 1368 : } ; 1369 : STBI_FREE(data); ; 1370 : return output; ; 1371 : } ; 1372 : #endif ; 1373 : ; 1374 : ////////////////////////////////////////////////////////////////////////////// ; 1375 : // ; 1376 : // "baseline" JPEG/JFIF decoder ; 1377 : // ; 1378 : // simple implementation ; 1379 : // - doesn't support delayed output of y-dimension ; 1380 : // - simple interface (only one output format: 8-bit interleaved RGB) ; 1381 : // - doesn't try to recover corrupt jpegs ; 1382 : // - doesn't allow partial loading, loading multiple at once ; 1383 : // - still fast on x86 (copying globals into locals doesn't help x86) ; 1384 : // - allocates lots of intermediate memory (full size of all components) ; 1385 : // - non-interleaved case requires this anyway ; 1386 : // - allows good upsampling (see next) ; 1387 : // high-quality ; 1388 : // - upsampled channels are bilinearly interpolated, even across blocks ; 1389 : // - quality integer IDCT derived from IJG's 'slow' ; 1390 : // performance ; 1391 : // - fast huffman; reasonable integer IDCT ; 1392 : // - some SIMD kernels for common paths on targets with SSE2/NEON ; 1393 : // - uses a lot of intermediate memory, could cache poorly ; 1394 : ; 1395 : #ifndef STBI_NO_JPEG ; 1396 : ; 1397 : // huffman decoding acceleration ; 1398 : #define FAST_BITS 9 // larger handles more cases; smaller stomps less cache ; 1399 : ; 1400 : typedef struct ; 1401 : { ; 1402 : stbi_uc fast[1 << FAST_BITS]; ; 1403 : // weirdly, repacking this into AoS is a 10% speed loss, instead of a win ; 1404 : stbi__uint16 code[256]; ; 1405 : stbi_uc values[256]; ; 1406 : stbi_uc size[257]; ; 1407 : unsigned int maxcode[18]; ; 1408 : int delta[17]; // old 'firstsymbol' - old 'firstcode' ; 1409 : } stbi__huffman; ; 1410 : ; 1411 : typedef struct ; 1412 : { ; 1413 : stbi__context* s; ; 1414 : stbi__huffman huff_dc[4]; ; 1415 : stbi__huffman huff_ac[4]; ; 1416 : stbi__uint16 dequant[4][64]; ; 1417 : stbi__int16 fast_ac[4][1 << FAST_BITS]; ; 1418 : ; 1419 : // sizes for components, interleaved MCUs ; 1420 : int img_h_max, img_v_max; ; 1421 : int img_mcu_x, img_mcu_y; ; 1422 : int img_mcu_w, img_mcu_h; ; 1423 : ; 1424 : // definition of jpeg image component ; 1425 : struct ; 1426 : { ; 1427 : int id; ; 1428 : int h, v; ; 1429 : int tq; ; 1430 : int hd, ha; ; 1431 : int dc_pred; ; 1432 : ; 1433 : int x, y, w2, h2; ; 1434 : stbi_uc* data; ; 1435 : void* raw_data, * raw_coeff; ; 1436 : stbi_uc* linebuf; ; 1437 : short* coeff; // progressive only ; 1438 : int coeff_w, coeff_h; // number of 8x8 coefficient blocks ; 1439 : } img_comp[4]; ; 1440 : ; 1441 : stbi__uint32 code_buffer; // jpeg entropy-coded buffer ; 1442 : int code_bits; // number of valid bits ; 1443 : unsigned char marker; // marker seen while filling entropy buffer ; 1444 : int nomore; // flag if we saw a marker so must stop ; 1445 : ; 1446 : int progressive; ; 1447 : int spec_start; ; 1448 : int spec_end; ; 1449 : int succ_high; ; 1450 : int succ_low; ; 1451 : int eob_run; ; 1452 : int jfif; ; 1453 : int app14_color_transform; // Adobe APP14 tag ; 1454 : int rgb; ; 1455 : ; 1456 : int scan_n, order[4]; ; 1457 : int restart_interval, todo; ; 1458 : ; 1459 : // kernels ; 1460 : void (*idct_block_kernel)(stbi_uc* out, int out_stride, short data[64]); ; 1461 : void (*YCbCr_to_RGB_kernel)(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step); ; 1462 : stbi_uc* (*resample_row_hv_2_kernel)(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs); ; 1463 : } stbi__jpeg; ; 1464 : ; 1465 : static int stbi__build_huffman(stbi__huffman* h, int* count) ; 1466 : { ; 1467 : int i, j, k = 0; ; 1468 : unsigned int code; ; 1469 : // build size list for each symbol (from JPEG spec) ; 1470 : for (i = 0; i < 16; ++i) { ; 1471 : for (j = 0; j < count[i]; ++j) { ; 1472 : h->size[k++] = (stbi_uc)(i + 1); ; 1473 : if (k >= 257) return stbi__err("bad size list", "Corrupt JPEG"); ; 1474 : } ; 1475 : } ; 1476 : h->size[k] = 0; ; 1477 : ; 1478 : // compute actual symbols (from jpeg spec) ; 1479 : code = 0; ; 1480 : k = 0; ; 1481 : for (j = 1; j <= 16; ++j) { ; 1482 : // compute delta to add to code to compute symbol id ; 1483 : h->delta[j] = k - code; ; 1484 : if (h->size[k] == j) { ; 1485 : while (h->size[k] == j) ; 1486 : h->code[k++] = (stbi__uint16)(code++); ; 1487 : if (code - 1 >= (1u << j)) return stbi__err("bad code lengths", "Corrupt JPEG"); ; 1488 : } ; 1489 : // compute largest code + 1 for this size, preshifted as needed later ; 1490 : h->maxcode[j] = code << (16 - j); ; 1491 : code <<= 1; ; 1492 : } ; 1493 : h->maxcode[j] = 0xffffffff; ; 1494 : ; 1495 : // build non-spec acceleration table; 255 is flag for not-accelerated ; 1496 : memset(h->fast, 255, 1 << FAST_BITS); ; 1497 : for (i = 0; i < k; ++i) { ; 1498 : int s = h->size[i]; ; 1499 : if (s <= FAST_BITS) { ; 1500 : int c = h->code[i] << (FAST_BITS - s); ; 1501 : int m = 1 << (FAST_BITS - s); ; 1502 : for (j = 0; j < m; ++j) { ; 1503 : h->fast[c + j] = (stbi_uc)i; ; 1504 : } ; 1505 : } ; 1506 : } ; 1507 : return 1; ; 1508 : } ; 1509 : ; 1510 : // build a table that decodes both magnitude and value of small ACs in ; 1511 : // one go. ; 1512 : static void stbi__build_fast_ac(stbi__int16* fast_ac, stbi__huffman* h) ; 1513 : { ; 1514 : int i; ; 1515 : for (i = 0; i < (1 << FAST_BITS); ++i) { ; 1516 : stbi_uc fast = h->fast[i]; ; 1517 : fast_ac[i] = 0; ; 1518 : if (fast < 255) { ; 1519 : int rs = h->values[fast]; ; 1520 : int run = (rs >> 4) & 15; ; 1521 : int magbits = rs & 15; ; 1522 : int len = h->size[fast]; ; 1523 : ; 1524 : if (magbits && len + magbits <= FAST_BITS) { ; 1525 : // magnitude code followed by receive_extend code ; 1526 : int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); ; 1527 : int m = 1 << (magbits - 1); ; 1528 : if (k < m) k += (~0U << magbits) + 1; ; 1529 : // if the result is small enough, we can fit it in fast_ac table ; 1530 : if (k >= -128 && k <= 127) ; 1531 : fast_ac[i] = (stbi__int16)((k * 256) + (run * 16) + (len + magbits)); ; 1532 : } ; 1533 : } ; 1534 : } ; 1535 : } ; 1536 : ; 1537 : static void stbi__grow_buffer_unsafe(stbi__jpeg* j) ; 1538 : { ; 1539 : do { ; 1540 : unsigned int b = j->nomore ? 0 : stbi__get8(j->s); ; 1541 : if (b == 0xff) { ; 1542 : int c = stbi__get8(j->s); ; 1543 : while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes ; 1544 : if (c != 0) { ; 1545 : j->marker = (unsigned char)c; ; 1546 : j->nomore = 1; ; 1547 : return; ; 1548 : } ; 1549 : } ; 1550 : j->code_buffer |= b << (24 - j->code_bits); ; 1551 : j->code_bits += 8; ; 1552 : } while (j->code_bits <= 24); ; 1553 : } ; 1554 : ; 1555 : // (1 << n) - 1 ; 1556 : static const stbi__uint32 stbi__bmask[17] = { 0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535 }; ; 1557 : ; 1558 : // decode a jpeg huffman value from the bitstream ; 1559 : stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg* j, stbi__huffman* h) ; 1560 : { ; 1561 : unsigned int temp; ; 1562 : int c, k; ; 1563 : ; 1564 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1565 : ; 1566 : // look at the top FAST_BITS and determine what symbol ID it is, ; 1567 : // if the code is <= FAST_BITS ; 1568 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1569 : k = h->fast[c]; ; 1570 : if (k < 255) { ; 1571 : int s = h->size[k]; ; 1572 : if (s > j->code_bits) ; 1573 : return -1; ; 1574 : j->code_buffer <<= s; ; 1575 : j->code_bits -= s; ; 1576 : return h->values[k]; ; 1577 : } ; 1578 : ; 1579 : // naive test is to shift the code_buffer down so k bits are ; 1580 : // valid, then test against maxcode. To speed this up, we've ; 1581 : // preshifted maxcode left so that it has (16-k) 0s at the ; 1582 : // end; in other words, regardless of the number of bits, it ; 1583 : // wants to be compared against something shifted to have 16; ; 1584 : // that way we don't need to shift inside the loop. ; 1585 : temp = j->code_buffer >> 16; ; 1586 : for (k = FAST_BITS + 1; ; ++k) ; 1587 : if (temp < h->maxcode[k]) ; 1588 : break; ; 1589 : if (k == 17) { ; 1590 : // error! code not found ; 1591 : j->code_bits -= 16; ; 1592 : return -1; ; 1593 : } ; 1594 : ; 1595 : if (k > j->code_bits) ; 1596 : return -1; ; 1597 : ; 1598 : // convert the huffman code to the symbol id ; 1599 : c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; ; 1600 : if (c < 0 || c >= 256) // symbol id out of bounds! ; 1601 : return -1; ; 1602 : STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); ; 1603 : ; 1604 : // convert the id to a symbol ; 1605 : j->code_bits -= k; ; 1606 : j->code_buffer <<= k; ; 1607 : return h->values[c]; ; 1608 : } ; 1609 : ; 1610 : // bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); ; 1620 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1621 : ; 1622 : sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative) ; 1623 : k = stbi_lrot(j->code_buffer, n); ; 1624 : j->code_buffer = k & ~stbi__bmask[n]; ; 1625 : k &= stbi__bmask[n]; ; 1626 : j->code_bits -= n; ; 1627 : return k + (stbi__jbias[n] & (sgn - 1)); ; 1628 : } ; 1629 : ; 1630 : // get some unsigned bits ; 1631 : stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg* j, int n) ; 1632 : { ; 1633 : unsigned int k; ; 1634 : if (j->code_bits < n) stbi__grow_buffer_unsafe(j); ; 1635 : if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1636 : k = stbi_lrot(j->code_buffer, n); ; 1637 : j->code_buffer = k & ~stbi__bmask[n]; ; 1638 : k &= stbi__bmask[n]; ; 1639 : j->code_bits -= n; ; 1640 : return k; ; 1641 : } ; 1642 : ; 1643 : stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg* j) ; 1644 : { ; 1645 : unsigned int k; ; 1646 : if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); ; 1647 : if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing ; 1648 : k = j->code_buffer; ; 1649 : j->code_buffer <<= 1; ; 1650 : --j->code_bits; ; 1651 : return k & 0x80000000; ; 1652 : } ; 1653 : ; 1654 : // given a value that's at position X in the zigzag stream, ; 1655 : // where does it appear in the 8x8 matrix coded as row-major? ; 1656 : static const stbi_uc stbi__jpeg_dezigzag[64 + 15] = ; 1657 : { ; 1658 : 0, 1, 8, 16, 9, 2, 3, 10, ; 1659 : 17, 24, 32, 25, 18, 11, 4, 5, ; 1660 : 12, 19, 26, 33, 40, 48, 41, 34, ; 1661 : 27, 20, 13, 6, 7, 14, 21, 28, ; 1662 : 35, 42, 49, 56, 57, 50, 43, 36, ; 1663 : 29, 22, 15, 23, 30, 37, 44, 51, ; 1664 : 58, 59, 52, 45, 38, 31, 39, 46, ; 1665 : 53, 60, 61, 54, 47, 55, 62, 63, ; 1666 : // let corrupt input sample past end ; 1667 : 63, 63, 63, 63, 63, 63, 63, 63, ; 1668 : 63, 63, 63, 63, 63, 63, 63 ; 1669 : }; ; 1670 : ; 1671 : // decode one 64-entry block-- ; 1672 : static int stbi__jpeg_decode_block(stbi__jpeg* j, short data[64], stbi__huffman* hdc, stbi__huffman* hac, stbi__int16* fac, int b, stbi__uint16* dequant) ; 1673 : { ; 1674 : int diff, dc, k; ; 1675 : int t; ; 1676 : ; 1677 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1678 : t = stbi__jpeg_huff_decode(j, hdc); ; 1679 : if (t < 0 || t > 15) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1680 : ; 1681 : // 0 all the ac values now so we can do it 32-bits at a time ; 1682 : memset(data, 0, 64 * sizeof(data[0])); ; 1683 : ; 1684 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1685 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1686 : dc = j->img_comp[b].dc_pred + diff; ; 1687 : j->img_comp[b].dc_pred = dc; ; 1688 : if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1689 : data[0] = (short)(dc * dequant[0]); ; 1690 : ; 1691 : // decode AC components, see JPEG spec ; 1692 : k = 1; ; 1693 : do { ; 1694 : unsigned int zig; ; 1695 : int c, r, s; ; 1696 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1697 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1698 : r = fac[c]; ; 1699 : if (r) { // fast-AC path ; 1700 : k += (r >> 4) & 15; // run ; 1701 : s = r & 15; // combined length ; 1702 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1703 : j->code_buffer <<= s; ; 1704 : j->code_bits -= s; ; 1705 : // decode into unzigzag'd location ; 1706 : zig = stbi__jpeg_dezigzag[k++]; ; 1707 : data[zig] = (short)((r >> 8) * dequant[zig]); ; 1708 : } ; 1709 : else { ; 1710 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1711 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1712 : s = rs & 15; ; 1713 : r = rs >> 4; ; 1714 : if (s == 0) { ; 1715 : if (rs != 0xf0) break; // end block ; 1716 : k += 16; ; 1717 : } ; 1718 : else { ; 1719 : k += r; ; 1720 : // decode into unzigzag'd location ; 1721 : zig = stbi__jpeg_dezigzag[k++]; ; 1722 : data[zig] = (short)(stbi__extend_receive(j, s) * dequant[zig]); ; 1723 : } ; 1724 : } ; 1725 : } while (k < 64); ; 1726 : return 1; ; 1727 : } ; 1728 : ; 1729 : static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg* j, short data[64], stbi__huffman* hdc, int b) ; 1730 : { ; 1731 : int diff, dc; ; 1732 : int t; ; 1733 : if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1734 : ; 1735 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1736 : ; 1737 : if (j->succ_high == 0) { ; 1738 : // first scan for DC coefficient, must be first ; 1739 : memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now ; 1740 : t = stbi__jpeg_huff_decode(j, hdc); ; 1741 : if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1742 : diff = t ? stbi__extend_receive(j, t) : 0; ; 1743 : ; 1744 : if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG"); ; 1745 : dc = j->img_comp[b].dc_pred + diff; ; 1746 : j->img_comp[b].dc_pred = dc; ; 1747 : if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1748 : data[0] = (short)(dc * (1 << j->succ_low)); ; 1749 : } ; 1750 : else { ; 1751 : // refinement scan for DC coefficient ; 1752 : if (stbi__jpeg_get_bit(j)) ; 1753 : data[0] += (short)(1 << j->succ_low); ; 1754 : } ; 1755 : return 1; ; 1756 : } ; 1757 : ; 1758 : // @OPTIMIZE: store non-zigzagged during the decode passes, ; 1759 : // and only de-zigzag when dequantizing ; 1760 : static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg* j, short data[64], stbi__huffman* hac, stbi__int16* fac) ; 1761 : { ; 1762 : int k; ; 1763 : if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); ; 1764 : ; 1765 : if (j->succ_high == 0) { ; 1766 : int shift = j->succ_low; ; 1767 : ; 1768 : if (j->eob_run) { ; 1769 : --j->eob_run; ; 1770 : return 1; ; 1771 : } ; 1772 : ; 1773 : k = j->spec_start; ; 1774 : do { ; 1775 : unsigned int zig; ; 1776 : int c, r, s; ; 1777 : if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); ; 1778 : c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); ; 1779 : r = fac[c]; ; 1780 : if (r) { // fast-AC path ; 1781 : k += (r >> 4) & 15; // run ; 1782 : s = r & 15; // combined length ; 1783 : if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available"); ; 1784 : j->code_buffer <<= s; ; 1785 : j->code_bits -= s; ; 1786 : zig = stbi__jpeg_dezigzag[k++]; ; 1787 : data[zig] = (short)((r >> 8) * (1 << shift)); ; 1788 : } ; 1789 : else { ; 1790 : int rs = stbi__jpeg_huff_decode(j, hac); ; 1791 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1792 : s = rs & 15; ; 1793 : r = rs >> 4; ; 1794 : if (s == 0) { ; 1795 : if (r < 15) { ; 1796 : j->eob_run = (1 << r); ; 1797 : if (r) ; 1798 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1799 : --j->eob_run; ; 1800 : break; ; 1801 : } ; 1802 : k += 16; ; 1803 : } ; 1804 : else { ; 1805 : k += r; ; 1806 : zig = stbi__jpeg_dezigzag[k++]; ; 1807 : data[zig] = (short)(stbi__extend_receive(j, s) * (1 << shift)); ; 1808 : } ; 1809 : } ; 1810 : } while (k <= j->spec_end); ; 1811 : } ; 1812 : else { ; 1813 : // refinement scan for these AC coefficients ; 1814 : ; 1815 : short bit = (short)(1 << j->succ_low); ; 1816 : ; 1817 : if (j->eob_run) { ; 1818 : --j->eob_run; ; 1819 : for (k = j->spec_start; k <= j->spec_end; ++k) { ; 1820 : short* p = &data[stbi__jpeg_dezigzag[k]]; ; 1821 : if (*p != 0) ; 1822 : if (stbi__jpeg_get_bit(j)) ; 1823 : if ((*p & bit) == 0) { ; 1824 : if (*p > 0) ; 1825 : *p += bit; ; 1826 : else ; 1827 : *p -= bit; ; 1828 : } ; 1829 : } ; 1830 : } ; 1831 : else { ; 1832 : k = j->spec_start; ; 1833 : do { ; 1834 : int r, s; ; 1835 : int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh ; 1836 : if (rs < 0) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1837 : s = rs & 15; ; 1838 : r = rs >> 4; ; 1839 : if (s == 0) { ; 1840 : if (r < 15) { ; 1841 : j->eob_run = (1 << r) - 1; ; 1842 : if (r) ; 1843 : j->eob_run += stbi__jpeg_get_bits(j, r); ; 1844 : r = 64; // force end of block ; 1845 : } ; 1846 : else { ; 1847 : // r=15 s=0 should write 16 0s, so we just do ; 1848 : // a run of 15 0s and then write s (which is 0), ; 1849 : // so we don't have to do anything special here ; 1850 : } ; 1851 : } ; 1852 : else { ; 1853 : if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); ; 1854 : // sign bit ; 1855 : if (stbi__jpeg_get_bit(j)) ; 1856 : s = bit; ; 1857 : else ; 1858 : s = -bit; ; 1859 : } ; 1860 : ; 1861 : // advance by r ; 1862 : while (k <= j->spec_end) { ; 1863 : short* p = &data[stbi__jpeg_dezigzag[k++]]; ; 1864 : if (*p != 0) { ; 1865 : if (stbi__jpeg_get_bit(j)) ; 1866 : if ((*p & bit) == 0) { ; 1867 : if (*p > 0) ; 1868 : *p += bit; ; 1869 : else ; 1870 : *p -= bit; ; 1871 : } ; 1872 : } ; 1873 : else { ; 1874 : if (r == 0) { ; 1875 : *p = (short)s; ; 1876 : break; ; 1877 : } ; 1878 : --r; ; 1879 : } ; 1880 : } ; 1881 : } while (k <= j->spec_end); ; 1882 : } ; 1883 : } ; 1884 : return 1; ; 1885 : } ; 1886 : ; 1887 : // take a -128..127 value and stbi__clamp it and convert to 0..255 ; 1888 : stbi_inline static stbi_uc stbi__clamp(int x) ; 1889 : { ; 1890 : // trick to use a single test to catch both cases ; 1891 : if ((unsigned int)x > 255) { ; 1892 : if (x < 0) return 0; ; 1893 : if (x > 255) return 255; ; 1894 : } ; 1895 : return (stbi_uc)x; ; 1896 : } ; 1897 : ; 1898 : #define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) ; 1899 : #define stbi__fsh(x) ((x) * 4096) ; 1900 : ; 1901 : // derived from jidctint -- DCT_ISLOW ; 1902 : #define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ ; 1903 : int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ ; 1904 : p2 = s2; \ ; 1905 : p3 = s6; \ ; 1906 : p1 = (p2+p3) * stbi__f2f(0.5411961f); \ ; 1907 : t2 = p1 + p3*stbi__f2f(-1.847759065f); \ ; 1908 : t3 = p1 + p2*stbi__f2f( 0.765366865f); \ ; 1909 : p2 = s0; \ ; 1910 : p3 = s4; \ ; 1911 : t0 = stbi__fsh(p2+p3); \ ; 1912 : t1 = stbi__fsh(p2-p3); \ ; 1913 : x0 = t0+t3; \ ; 1914 : x3 = t0-t3; \ ; 1915 : x1 = t1+t2; \ ; 1916 : x2 = t1-t2; \ ; 1917 : t0 = s7; \ ; 1918 : t1 = s5; \ ; 1919 : t2 = s3; \ ; 1920 : t3 = s1; \ ; 1921 : p3 = t0+t2; \ ; 1922 : p4 = t1+t3; \ ; 1923 : p1 = t0+t3; \ ; 1924 : p2 = t1+t2; \ ; 1925 : p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ ; 1926 : t0 = t0*stbi__f2f( 0.298631336f); \ ; 1927 : t1 = t1*stbi__f2f( 2.053119869f); \ ; 1928 : t2 = t2*stbi__f2f( 3.072711026f); \ ; 1929 : t3 = t3*stbi__f2f( 1.501321110f); \ ; 1930 : p1 = p5 + p1*stbi__f2f(-0.899976223f); \ ; 1931 : p2 = p5 + p2*stbi__f2f(-2.562915447f); \ ; 1932 : p3 = p3*stbi__f2f(-1.961570560f); \ ; 1933 : p4 = p4*stbi__f2f(-0.390180644f); \ ; 1934 : t3 += p1+p4; \ ; 1935 : t2 += p2+p3; \ ; 1936 : t1 += p2+p4; \ ; 1937 : t0 += p1+p3; ; 1938 : ; 1939 : static void stbi__idct_block(stbi_uc* out, int out_stride, short data[64]) ; 1940 : { ; 1941 : int i, val[64], * v = val; ; 1942 : stbi_uc* o; ; 1943 : short* d = data; ; 1944 : ; 1945 : // columns ; 1946 : for (i = 0; i < 8; ++i, ++d, ++v) { ; 1947 : // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing ; 1948 : if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 ; 1949 : && d[40] == 0 && d[48] == 0 && d[56] == 0) { ; 1950 : // no shortcut 0 seconds ; 1951 : // (1|2|3|4|5|6|7)==0 0 seconds ; 1952 : // all separate -0.047 seconds ; 1953 : // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds ; 1954 : int dcterm = d[0] * 4; ; 1955 : v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; ; 1956 : } ; 1957 : else { ; 1958 : STBI__IDCT_1D(d[0], d[8], d[16], d[24], d[32], d[40], d[48], d[56]) ; 1959 : // constants scaled things up by 1<<12; let's bring them back ; 1960 : // down, but keep 2 extra bits of precision ; 1961 : x0 += 512; x1 += 512; x2 += 512; x3 += 512; ; 1962 : v[0] = (x0 + t3) >> 10; ; 1963 : v[56] = (x0 - t3) >> 10; ; 1964 : v[8] = (x1 + t2) >> 10; ; 1965 : v[48] = (x1 - t2) >> 10; ; 1966 : v[16] = (x2 + t1) >> 10; ; 1967 : v[40] = (x2 - t1) >> 10; ; 1968 : v[24] = (x3 + t0) >> 10; ; 1969 : v[32] = (x3 - t0) >> 10; ; 1970 : } ; 1971 : } ; 1972 : ; 1973 : for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) { ; 1974 : // no fast case since the first 1D IDCT spread components out ; 1975 : STBI__IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) ; 1976 : // constants scaled things up by 1<<12, plus we had 1<<2 from first ; 1977 : // loop, plus horizontal and vertical each scale by sqrt(8) so together ; 1978 : // we've got an extra 1<<3, so 1<<17 total we need to remove. ; 1979 : // so we want to round that, which means adding 0.5 * 1<<17, ; 1980 : // aka 65536. Also, we'll end up with -128 to 127 that we want ; 1981 : // to encode as 0..255 by adding 128, so we'll add that before the shift ; 1982 : x0 += 65536 + (128 << 17); ; 1983 : x1 += 65536 + (128 << 17); ; 1984 : x2 += 65536 + (128 << 17); ; 1985 : x3 += 65536 + (128 << 17); ; 1986 : // tried computing the shifts into temps, or'ing the temps to see ; 1987 : // if any were out of range, but that was slower ; 1988 : o[0] = stbi__clamp((x0 + t3) >> 17); ; 1989 : o[7] = stbi__clamp((x0 - t3) >> 17); ; 1990 : o[1] = stbi__clamp((x1 + t2) >> 17); ; 1991 : o[6] = stbi__clamp((x1 - t2) >> 17); ; 1992 : o[2] = stbi__clamp((x2 + t1) >> 17); ; 1993 : o[5] = stbi__clamp((x2 - t1) >> 17); ; 1994 : o[3] = stbi__clamp((x3 + t0) >> 17); ; 1995 : o[4] = stbi__clamp((x3 - t0) >> 17); ; 1996 : } ; 1997 : } ; 1998 : ; 1999 : #ifdef STBI_SSE2 ; 2000 : // sse2 integer IDCT. not the fastest possible implementation but it ; 2001 : // produces bit-identical results to the generic C version so it's ; 2002 : // fully "transparent". ; 2003 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2004 : { ; 2005 : // This is constructed to match our regular (generic) integer IDCT exactly. ; 2006 : __m128i row0, row1, row2, row3, row4, row5, row6, row7; ; 2007 : __m128i tmp; ; 2008 : ; 2009 : // dot product constant: even elems=x, odd elems=y ; 2010 : #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) ; 2011 : ; 2012 : // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) ; 2013 : // out(1) = c1[even]*x + c1[odd]*y ; 2014 : #define dct_rot(out0,out1, x,y,c0,c1) \ ; 2015 : __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ ; 2016 : __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ ; 2017 : __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ ; 2018 : __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ ; 2019 : __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ ; 2020 : __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) ; 2021 : ; 2022 : // out = in << 12 (in 16-bit, out 32-bit) ; 2023 : #define dct_widen(out, in) \ ; 2024 : __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ ; 2025 : __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) ; 2026 : ; 2027 : // wide add ; 2028 : #define dct_wadd(out, a, b) \ ; 2029 : __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ ; 2030 : __m128i out##_h = _mm_add_epi32(a##_h, b##_h) ; 2031 : ; 2032 : // wide sub ; 2033 : #define dct_wsub(out, a, b) \ ; 2034 : __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ ; 2035 : __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) ; 2036 : ; 2037 : // butterfly a/b, add bias, then shift by "s" and pack ; 2038 : #define dct_bfly32o(out0, out1, a,b,bias,s) \ ; 2039 : { \ ; 2040 : __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ ; 2041 : __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ ; 2042 : dct_wadd(sum, abiased, b); \ ; 2043 : dct_wsub(dif, abiased, b); \ ; 2044 : out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ ; 2045 : out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ ; 2046 : } ; 2047 : ; 2048 : // 8-bit interleave step (for transposes) ; 2049 : #define dct_interleave8(a, b) \ ; 2050 : tmp = a; \ ; 2051 : a = _mm_unpacklo_epi8(a, b); \ ; 2052 : b = _mm_unpackhi_epi8(tmp, b) ; 2053 : ; 2054 : // 16-bit interleave step (for transposes) ; 2055 : #define dct_interleave16(a, b) \ ; 2056 : tmp = a; \ ; 2057 : a = _mm_unpacklo_epi16(a, b); \ ; 2058 : b = _mm_unpackhi_epi16(tmp, b) ; 2059 : ; 2060 : #define dct_pass(bias,shift) \ ; 2061 : { \ ; 2062 : /* even part */ \ ; 2063 : dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ ; 2064 : __m128i sum04 = _mm_add_epi16(row0, row4); \ ; 2065 : __m128i dif04 = _mm_sub_epi16(row0, row4); \ ; 2066 : dct_widen(t0e, sum04); \ ; 2067 : dct_widen(t1e, dif04); \ ; 2068 : dct_wadd(x0, t0e, t3e); \ ; 2069 : dct_wsub(x3, t0e, t3e); \ ; 2070 : dct_wadd(x1, t1e, t2e); \ ; 2071 : dct_wsub(x2, t1e, t2e); \ ; 2072 : /* odd part */ \ ; 2073 : dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ ; 2074 : dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ ; 2075 : __m128i sum17 = _mm_add_epi16(row1, row7); \ ; 2076 : __m128i sum35 = _mm_add_epi16(row3, row5); \ ; 2077 : dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ ; 2078 : dct_wadd(x4, y0o, y4o); \ ; 2079 : dct_wadd(x5, y1o, y5o); \ ; 2080 : dct_wadd(x6, y2o, y5o); \ ; 2081 : dct_wadd(x7, y3o, y4o); \ ; 2082 : dct_bfly32o(row0,row7, x0,x7,bias,shift); \ ; 2083 : dct_bfly32o(row1,row6, x1,x6,bias,shift); \ ; 2084 : dct_bfly32o(row2,row5, x2,x5,bias,shift); \ ; 2085 : dct_bfly32o(row3,row4, x3,x4,bias,shift); \ ; 2086 : } ; 2087 : ; 2088 : __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); ; 2089 : __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f(0.765366865f), stbi__f2f(0.5411961f)); ; 2090 : __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); ; 2091 : __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); ; 2092 : __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f(0.298631336f), stbi__f2f(-1.961570560f)); ; 2093 : __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f(3.072711026f)); ; 2094 : __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f(2.053119869f), stbi__f2f(-0.390180644f)); ; 2095 : __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f(1.501321110f)); ; 2096 : ; 2097 : // rounding biases in column/row passes, see stbi__idct_block for explanation. ; 2098 : __m128i bias_0 = _mm_set1_epi32(512); ; 2099 : __m128i bias_1 = _mm_set1_epi32(65536 + (128 << 17)); ; 2100 : ; 2101 : // load ; 2102 : row0 = _mm_load_si128((const __m128i*) (data + 0 * 8)); ; 2103 : row1 = _mm_load_si128((const __m128i*) (data + 1 * 8)); ; 2104 : row2 = _mm_load_si128((const __m128i*) (data + 2 * 8)); ; 2105 : row3 = _mm_load_si128((const __m128i*) (data + 3 * 8)); ; 2106 : row4 = _mm_load_si128((const __m128i*) (data + 4 * 8)); ; 2107 : row5 = _mm_load_si128((const __m128i*) (data + 5 * 8)); ; 2108 : row6 = _mm_load_si128((const __m128i*) (data + 6 * 8)); ; 2109 : row7 = _mm_load_si128((const __m128i*) (data + 7 * 8)); ; 2110 : ; 2111 : // column pass ; 2112 : dct_pass(bias_0, 10); ; 2113 : ; 2114 : { ; 2115 : // 16bit 8x8 transpose pass 1 ; 2116 : dct_interleave16(row0, row4); ; 2117 : dct_interleave16(row1, row5); ; 2118 : dct_interleave16(row2, row6); ; 2119 : dct_interleave16(row3, row7); ; 2120 : ; 2121 : // transpose pass 2 ; 2122 : dct_interleave16(row0, row2); ; 2123 : dct_interleave16(row1, row3); ; 2124 : dct_interleave16(row4, row6); ; 2125 : dct_interleave16(row5, row7); ; 2126 : ; 2127 : // transpose pass 3 ; 2128 : dct_interleave16(row0, row1); ; 2129 : dct_interleave16(row2, row3); ; 2130 : dct_interleave16(row4, row5); ; 2131 : dct_interleave16(row6, row7); ; 2132 : } ; 2133 : ; 2134 : // row pass ; 2135 : dct_pass(bias_1, 17); ; 2136 : ; 2137 : { ; 2138 : // pack ; 2139 : __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 ; 2140 : __m128i p1 = _mm_packus_epi16(row2, row3); ; 2141 : __m128i p2 = _mm_packus_epi16(row4, row5); ; 2142 : __m128i p3 = _mm_packus_epi16(row6, row7); ; 2143 : ; 2144 : // 8bit 8x8 transpose pass 1 ; 2145 : dct_interleave8(p0, p2); // a0e0a1e1... ; 2146 : dct_interleave8(p1, p3); // c0g0c1g1... ; 2147 : ; 2148 : // transpose pass 2 ; 2149 : dct_interleave8(p0, p1); // a0c0e0g0... ; 2150 : dct_interleave8(p2, p3); // b0d0f0h0... ; 2151 : ; 2152 : // transpose pass 3 ; 2153 : dct_interleave8(p0, p2); // a0b0c0d0... ; 2154 : dct_interleave8(p1, p3); // a4b4c4d4... ; 2155 : ; 2156 : // store ; 2157 : _mm_storel_epi64((__m128i*) out, p0); out += out_stride; ; 2158 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; ; 2159 : _mm_storel_epi64((__m128i*) out, p2); out += out_stride; ; 2160 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; ; 2161 : _mm_storel_epi64((__m128i*) out, p1); out += out_stride; ; 2162 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; ; 2163 : _mm_storel_epi64((__m128i*) out, p3); out += out_stride; ; 2164 : _mm_storel_epi64((__m128i*) out, _mm_shuffle_epi32(p3, 0x4e)); ; 2165 : } ; 2166 : ; 2167 : #undef dct_const ; 2168 : #undef dct_rot ; 2169 : #undef dct_widen ; 2170 : #undef dct_wadd ; 2171 : #undef dct_wsub ; 2172 : #undef dct_bfly32o ; 2173 : #undef dct_interleave8 ; 2174 : #undef dct_interleave16 ; 2175 : #undef dct_pass ; 2176 : } ; 2177 : ; 2178 : #endif // STBI_SSE2 ; 2179 : ; 2180 : #ifdef STBI_NEON ; 2181 : ; 2182 : // NEON integer IDCT. should produce bit-identical ; 2183 : // results to the generic C version. ; 2184 : static void stbi__idct_simd(stbi_uc* out, int out_stride, short data[64]) ; 2185 : { ; 2186 : int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; ; 2187 : ; 2188 : int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); ; 2189 : int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); ; 2190 : int16x4_t rot0_2 = vdup_n_s16(stbi__f2f(0.765366865f)); ; 2191 : int16x4_t rot1_0 = vdup_n_s16(stbi__f2f(1.175875602f)); ; 2192 : int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); ; 2193 : int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); ; 2194 : int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); ; 2195 : int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); ; 2196 : int16x4_t rot3_0 = vdup_n_s16(stbi__f2f(0.298631336f)); ; 2197 : int16x4_t rot3_1 = vdup_n_s16(stbi__f2f(2.053119869f)); ; 2198 : int16x4_t rot3_2 = vdup_n_s16(stbi__f2f(3.072711026f)); ; 2199 : int16x4_t rot3_3 = vdup_n_s16(stbi__f2f(1.501321110f)); ; 2200 : ; 2201 : #define dct_long_mul(out, inq, coeff) \ ; 2202 : int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ ; 2203 : int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) ; 2204 : ; 2205 : #define dct_long_mac(out, acc, inq, coeff) \ ; 2206 : int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ ; 2207 : int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) ; 2208 : ; 2209 : #define dct_widen(out, inq) \ ; 2210 : int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ ; 2211 : int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) ; 2212 : ; 2213 : // wide add ; 2214 : #define dct_wadd(out, a, b) \ ; 2215 : int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ ; 2216 : int32x4_t out##_h = vaddq_s32(a##_h, b##_h) ; 2217 : ; 2218 : // wide sub ; 2219 : #define dct_wsub(out, a, b) \ ; 2220 : int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ ; 2221 : int32x4_t out##_h = vsubq_s32(a##_h, b##_h) ; 2222 : ; 2223 : // butterfly a/b, then shift using "shiftop" by "s" and pack ; 2224 : #define dct_bfly32o(out0,out1, a,b,shiftop,s) \ ; 2225 : { \ ; 2226 : dct_wadd(sum, a, b); \ ; 2227 : dct_wsub(dif, a, b); \ ; 2228 : out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ ; 2229 : out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ ; 2230 : } ; 2231 : ; 2232 : #define dct_pass(shiftop, shift) \ ; 2233 : { \ ; 2234 : /* even part */ \ ; 2235 : int16x8_t sum26 = vaddq_s16(row2, row6); \ ; 2236 : dct_long_mul(p1e, sum26, rot0_0); \ ; 2237 : dct_long_mac(t2e, p1e, row6, rot0_1); \ ; 2238 : dct_long_mac(t3e, p1e, row2, rot0_2); \ ; 2239 : int16x8_t sum04 = vaddq_s16(row0, row4); \ ; 2240 : int16x8_t dif04 = vsubq_s16(row0, row4); \ ; 2241 : dct_widen(t0e, sum04); \ ; 2242 : dct_widen(t1e, dif04); \ ; 2243 : dct_wadd(x0, t0e, t3e); \ ; 2244 : dct_wsub(x3, t0e, t3e); \ ; 2245 : dct_wadd(x1, t1e, t2e); \ ; 2246 : dct_wsub(x2, t1e, t2e); \ ; 2247 : /* odd part */ \ ; 2248 : int16x8_t sum15 = vaddq_s16(row1, row5); \ ; 2249 : int16x8_t sum17 = vaddq_s16(row1, row7); \ ; 2250 : int16x8_t sum35 = vaddq_s16(row3, row5); \ ; 2251 : int16x8_t sum37 = vaddq_s16(row3, row7); \ ; 2252 : int16x8_t sumodd = vaddq_s16(sum17, sum35); \ ; 2253 : dct_long_mul(p5o, sumodd, rot1_0); \ ; 2254 : dct_long_mac(p1o, p5o, sum17, rot1_1); \ ; 2255 : dct_long_mac(p2o, p5o, sum35, rot1_2); \ ; 2256 : dct_long_mul(p3o, sum37, rot2_0); \ ; 2257 : dct_long_mul(p4o, sum15, rot2_1); \ ; 2258 : dct_wadd(sump13o, p1o, p3o); \ ; 2259 : dct_wadd(sump24o, p2o, p4o); \ ; 2260 : dct_wadd(sump23o, p2o, p3o); \ ; 2261 : dct_wadd(sump14o, p1o, p4o); \ ; 2262 : dct_long_mac(x4, sump13o, row7, rot3_0); \ ; 2263 : dct_long_mac(x5, sump24o, row5, rot3_1); \ ; 2264 : dct_long_mac(x6, sump23o, row3, rot3_2); \ ; 2265 : dct_long_mac(x7, sump14o, row1, rot3_3); \ ; 2266 : dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ ; 2267 : dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ ; 2268 : dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ ; 2269 : dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ ; 2270 : } ; 2271 : ; 2272 : // load ; 2273 : row0 = vld1q_s16(data + 0 * 8); ; 2274 : row1 = vld1q_s16(data + 1 * 8); ; 2275 : row2 = vld1q_s16(data + 2 * 8); ; 2276 : row3 = vld1q_s16(data + 3 * 8); ; 2277 : row4 = vld1q_s16(data + 4 * 8); ; 2278 : row5 = vld1q_s16(data + 5 * 8); ; 2279 : row6 = vld1q_s16(data + 6 * 8); ; 2280 : row7 = vld1q_s16(data + 7 * 8); ; 2281 : ; 2282 : // add DC bias ; 2283 : row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); ; 2284 : ; 2285 : // column pass ; 2286 : dct_pass(vrshrn_n_s32, 10); ; 2287 : ; 2288 : // 16bit 8x8 transpose ; 2289 : { ; 2290 : // these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. ; 2291 : // whether compilers actually get this is another story, sadly. ; 2292 : #define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } ; 2293 : #define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } ; 2294 : #define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } ; 2295 : ; 2296 : // pass 1 ; 2297 : dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 ; 2298 : dct_trn16(row2, row3); ; 2299 : dct_trn16(row4, row5); ; 2300 : dct_trn16(row6, row7); ; 2301 : ; 2302 : // pass 2 ; 2303 : dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 ; 2304 : dct_trn32(row1, row3); ; 2305 : dct_trn32(row4, row6); ; 2306 : dct_trn32(row5, row7); ; 2307 : ; 2308 : // pass 3 ; 2309 : dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 ; 2310 : dct_trn64(row1, row5); ; 2311 : dct_trn64(row2, row6); ; 2312 : dct_trn64(row3, row7); ; 2313 : ; 2314 : #undef dct_trn16 ; 2315 : #undef dct_trn32 ; 2316 : #undef dct_trn64 ; 2317 : } ; 2318 : ; 2319 : // row pass ; 2320 : // vrshrn_n_s32 only supports shifts up to 16, we need ; 2321 : // 17. so do a non-rounding shift of 16 first then follow ; 2322 : // up with a rounding shift by 1. ; 2323 : dct_pass(vshrn_n_s32, 16); ; 2324 : ; 2325 : { ; 2326 : // pack and round ; 2327 : uint8x8_t p0 = vqrshrun_n_s16(row0, 1); ; 2328 : uint8x8_t p1 = vqrshrun_n_s16(row1, 1); ; 2329 : uint8x8_t p2 = vqrshrun_n_s16(row2, 1); ; 2330 : uint8x8_t p3 = vqrshrun_n_s16(row3, 1); ; 2331 : uint8x8_t p4 = vqrshrun_n_s16(row4, 1); ; 2332 : uint8x8_t p5 = vqrshrun_n_s16(row5, 1); ; 2333 : uint8x8_t p6 = vqrshrun_n_s16(row6, 1); ; 2334 : uint8x8_t p7 = vqrshrun_n_s16(row7, 1); ; 2335 : ; 2336 : // again, these can translate into one instruction, but often don't. ; 2337 : #define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } ; 2338 : #define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } ; 2339 : #define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } ; 2340 : ; 2341 : // sadly can't use interleaved stores here since we only write ; 2342 : // 8 bytes to each scan line! ; 2343 : ; 2344 : // 8x8 8-bit transpose pass 1 ; 2345 : dct_trn8_8(p0, p1); ; 2346 : dct_trn8_8(p2, p3); ; 2347 : dct_trn8_8(p4, p5); ; 2348 : dct_trn8_8(p6, p7); ; 2349 : ; 2350 : // pass 2 ; 2351 : dct_trn8_16(p0, p2); ; 2352 : dct_trn8_16(p1, p3); ; 2353 : dct_trn8_16(p4, p6); ; 2354 : dct_trn8_16(p5, p7); ; 2355 : ; 2356 : // pass 3 ; 2357 : dct_trn8_32(p0, p4); ; 2358 : dct_trn8_32(p1, p5); ; 2359 : dct_trn8_32(p2, p6); ; 2360 : dct_trn8_32(p3, p7); ; 2361 : ; 2362 : // store ; 2363 : vst1_u8(out, p0); out += out_stride; ; 2364 : vst1_u8(out, p1); out += out_stride; ; 2365 : vst1_u8(out, p2); out += out_stride; ; 2366 : vst1_u8(out, p3); out += out_stride; ; 2367 : vst1_u8(out, p4); out += out_stride; ; 2368 : vst1_u8(out, p5); out += out_stride; ; 2369 : vst1_u8(out, p6); out += out_stride; ; 2370 : vst1_u8(out, p7); ; 2371 : ; 2372 : #undef dct_trn8_8 ; 2373 : #undef dct_trn8_16 ; 2374 : #undef dct_trn8_32 ; 2375 : } ; 2376 : ; 2377 : #undef dct_long_mul ; 2378 : #undef dct_long_mac ; 2379 : #undef dct_widen ; 2380 : #undef dct_wadd ; 2381 : #undef dct_wsub ; 2382 : #undef dct_bfly32o ; 2383 : #undef dct_pass ; 2384 : } ; 2385 : ; 2386 : #endif // STBI_NEON ; 2387 : ; 2388 : #define STBI__MARKER_none 0xff ; 2389 : // if there's a pending marker from the entropy stream, return that ; 2390 : // otherwise, fetch from the stream and get a marker. if there's no ; 2391 : // marker, return 0xff, which is never a valid marker value ; 2392 : static stbi_uc stbi__get_marker(stbi__jpeg* j) ; 2393 : { ; 2394 : stbi_uc x; ; 2395 : if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } ; 2396 : x = stbi__get8(j->s); ; 2397 : if (x != 0xff) return STBI__MARKER_none; ; 2398 : while (x == 0xff) ; 2399 : x = stbi__get8(j->s); // consume repeated 0xff fill bytes ; 2400 : return x; ; 2401 : } ; 2402 : ; 2403 : // in each scan, we'll have scan_n components, and the order ; 2404 : // of the components is specified by order[] ; 2405 : #define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) ; 2406 : ; 2407 : // after a restart interval, stbi__jpeg_reset the entropy decoder and ; 2408 : // the dc prediction ; 2409 : static void stbi__jpeg_reset(stbi__jpeg* j) ; 2410 : { ; 2411 : j->code_bits = 0; ; 2412 : j->code_buffer = 0; ; 2413 : j->nomore = 0; ; 2414 : j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; ; 2415 : j->marker = STBI__MARKER_none; ; 2416 : j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; ; 2417 : j->eob_run = 0; ; 2418 : // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, ; 2419 : // since we don't even allow 1<<30 pixels ; 2420 : } ; 2421 : ; 2422 : static int stbi__parse_entropy_coded_data(stbi__jpeg* z) ; 2423 : { ; 2424 : stbi__jpeg_reset(z); ; 2425 : if (!z->progressive) { ; 2426 : if (z->scan_n == 1) { ; 2427 : int i, j; ; 2428 : STBI_SIMD_ALIGN(short, data[64]); ; 2429 : int n = z->order[0]; ; 2430 : // non-interleaved data, we just need to process one block at a time, ; 2431 : // in trivial scanline order ; 2432 : // number of blocks to do just depends on how many actual "pixels" this ; 2433 : // component has, independent of interleaved MCU blocking and such ; 2434 : int w = (z->img_comp[n].x + 7) >> 3; ; 2435 : int h = (z->img_comp[n].y + 7) >> 3; ; 2436 : for (j = 0; j < h; ++j) { ; 2437 : for (i = 0; i < w; ++i) { ; 2438 : int ha = z->img_comp[n].ha; ; 2439 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2440 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2441 : // every data block is an MCU, so countdown the restart interval ; 2442 : if (--z->todo <= 0) { ; 2443 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2444 : // if it's NOT a restart, then just bail, so we get corrupt data ; 2445 : // rather than no data ; 2446 : if (!STBI__RESTART(z->marker)) return 1; ; 2447 : stbi__jpeg_reset(z); ; 2448 : } ; 2449 : } ; 2450 : } ; 2451 : return 1; ; 2452 : } ; 2453 : else { // interleaved ; 2454 : int i, j, k, x, y; ; 2455 : STBI_SIMD_ALIGN(short, data[64]); ; 2456 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2457 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2458 : // scan an interleaved mcu... process scan_n components in order ; 2459 : for (k = 0; k < z->scan_n; ++k) { ; 2460 : int n = z->order[k]; ; 2461 : // scan out an mcu's worth of this component; that's just determined ; 2462 : // by the basic H and V specified for the component ; 2463 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2464 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2465 : int x2 = (i * z->img_comp[n].h + x) * 8; ; 2466 : int y2 = (j * z->img_comp[n].v + y) * 8; ; 2467 : int ha = z->img_comp[n].ha; ; 2468 : if (!stbi__jpeg_decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; ; 2469 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data); ; 2470 : } ; 2471 : } ; 2472 : } ; 2473 : // after all interleaved components, that's an interleaved MCU, ; 2474 : // so now count down the restart interval ; 2475 : if (--z->todo <= 0) { ; 2476 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2477 : if (!STBI__RESTART(z->marker)) return 1; ; 2478 : stbi__jpeg_reset(z); ; 2479 : } ; 2480 : } ; 2481 : } ; 2482 : return 1; ; 2483 : } ; 2484 : } ; 2485 : else { ; 2486 : if (z->scan_n == 1) { ; 2487 : int i, j; ; 2488 : int n = z->order[0]; ; 2489 : // non-interleaved data, we just need to process one block at a time, ; 2490 : // in trivial scanline order ; 2491 : // number of blocks to do just depends on how many actual "pixels" this ; 2492 : // component has, independent of interleaved MCU blocking and such ; 2493 : int w = (z->img_comp[n].x + 7) >> 3; ; 2494 : int h = (z->img_comp[n].y + 7) >> 3; ; 2495 : for (j = 0; j < h; ++j) { ; 2496 : for (i = 0; i < w; ++i) { ; 2497 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2498 : if (z->spec_start == 0) { ; 2499 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2500 : return 0; ; 2501 : } ; 2502 : else { ; 2503 : int ha = z->img_comp[n].ha; ; 2504 : if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) ; 2505 : return 0; ; 2506 : } ; 2507 : // every data block is an MCU, so countdown the restart interval ; 2508 : if (--z->todo <= 0) { ; 2509 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2510 : if (!STBI__RESTART(z->marker)) return 1; ; 2511 : stbi__jpeg_reset(z); ; 2512 : } ; 2513 : } ; 2514 : } ; 2515 : return 1; ; 2516 : } ; 2517 : else { // interleaved ; 2518 : int i, j, k, x, y; ; 2519 : for (j = 0; j < z->img_mcu_y; ++j) { ; 2520 : for (i = 0; i < z->img_mcu_x; ++i) { ; 2521 : // scan an interleaved mcu... process scan_n components in order ; 2522 : for (k = 0; k < z->scan_n; ++k) { ; 2523 : int n = z->order[k]; ; 2524 : // scan out an mcu's worth of this component; that's just determined ; 2525 : // by the basic H and V specified for the component ; 2526 : for (y = 0; y < z->img_comp[n].v; ++y) { ; 2527 : for (x = 0; x < z->img_comp[n].h; ++x) { ; 2528 : int x2 = (i * z->img_comp[n].h + x); ; 2529 : int y2 = (j * z->img_comp[n].v + y); ; 2530 : short* data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); ; 2531 : if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) ; 2532 : return 0; ; 2533 : } ; 2534 : } ; 2535 : } ; 2536 : // after all interleaved components, that's an interleaved MCU, ; 2537 : // so now count down the restart interval ; 2538 : if (--z->todo <= 0) { ; 2539 : if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); ; 2540 : if (!STBI__RESTART(z->marker)) return 1; ; 2541 : stbi__jpeg_reset(z); ; 2542 : } ; 2543 : } ; 2544 : } ; 2545 : return 1; ; 2546 : } ; 2547 : } ; 2548 : } ; 2549 : ; 2550 : static void stbi__jpeg_dequantize(short* data, stbi__uint16* dequant) ; 2551 : { ; 2552 : int i; ; 2553 : for (i = 0; i < 64; ++i) ; 2554 : data[i] *= dequant[i]; ; 2555 : } ; 2556 : ; 2557 : static void stbi__jpeg_finish(stbi__jpeg* z) ; 2558 : { ; 2559 : if (z->progressive) { ; 2560 : // dequantize and idct the data ; 2561 : int i, j, n; ; 2562 : for (n = 0; n < z->s->img_n; ++n) { ; 2563 : int w = (z->img_comp[n].x + 7) >> 3; ; 2564 : int h = (z->img_comp[n].y + 7) >> 3; ; 2565 : for (j = 0; j < h; ++j) { ; 2566 : for (i = 0; i < w; ++i) { ; 2567 : short* data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); ; 2568 : stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); ; 2569 : z->idct_block_kernel(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data); ; 2570 : } ; 2571 : } ; 2572 : } ; 2573 : } ; 2574 : } ; 2575 : ; 2576 : static int stbi__process_marker(stbi__jpeg* z, int m) ; 2577 : { ; 2578 : int L; ; 2579 : switch (m) { ; 2580 : case STBI__MARKER_none: // no marker found ; 2581 : return stbi__err("expected marker", "Corrupt JPEG"); ; 2582 : ; 2583 : case 0xDD: // DRI - specify restart interval ; 2584 : if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len", "Corrupt JPEG"); ; 2585 : z->restart_interval = stbi__get16be(z->s); ; 2586 : return 1; ; 2587 : ; 2588 : case 0xDB: // DQT - define quantization table ; 2589 : L = stbi__get16be(z->s) - 2; ; 2590 : while (L > 0) { ; 2591 : int q = stbi__get8(z->s); ; 2592 : int p = q >> 4, sixteen = (p != 0); ; 2593 : int t = q & 15, i; ; 2594 : if (p != 0 && p != 1) return stbi__err("bad DQT type", "Corrupt JPEG"); ; 2595 : if (t > 3) return stbi__err("bad DQT table", "Corrupt JPEG"); ; 2596 : ; 2597 : for (i = 0; i < 64; ++i) ; 2598 : z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); ; 2599 : L -= (sixteen ? 129 : 65); ; 2600 : } ; 2601 : return L == 0; ; 2602 : ; 2603 : case 0xC4: // DHT - define huffman table ; 2604 : L = stbi__get16be(z->s) - 2; ; 2605 : while (L > 0) { ; 2606 : stbi_uc* v; ; 2607 : int sizes[16], i, n = 0; ; 2608 : int q = stbi__get8(z->s); ; 2609 : int tc = q >> 4; ; 2610 : int th = q & 15; ; 2611 : if (tc > 1 || th > 3) return stbi__err("bad DHT header", "Corrupt JPEG"); ; 2612 : for (i = 0; i < 16; ++i) { ; 2613 : sizes[i] = stbi__get8(z->s); ; 2614 : n += sizes[i]; ; 2615 : } ; 2616 : if (n > 256) return stbi__err("bad DHT header", "Corrupt JPEG"); // Loop over i < n would write past end of values! ; 2617 : L -= 17; ; 2618 : if (tc == 0) { ; 2619 : if (!stbi__build_huffman(z->huff_dc + th, sizes)) return 0; ; 2620 : v = z->huff_dc[th].values; ; 2621 : } ; 2622 : else { ; 2623 : if (!stbi__build_huffman(z->huff_ac + th, sizes)) return 0; ; 2624 : v = z->huff_ac[th].values; ; 2625 : } ; 2626 : for (i = 0; i < n; ++i) ; 2627 : v[i] = stbi__get8(z->s); ; 2628 : if (tc != 0) ; 2629 : stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); ; 2630 : L -= n; ; 2631 : } ; 2632 : return L == 0; ; 2633 : } ; 2634 : ; 2635 : // check for comment block or APP blocks ; 2636 : if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { ; 2637 : L = stbi__get16be(z->s); ; 2638 : if (L < 2) { ; 2639 : if (m == 0xFE) ; 2640 : return stbi__err("bad COM len", "Corrupt JPEG"); ; 2641 : else ; 2642 : return stbi__err("bad APP len", "Corrupt JPEG"); ; 2643 : } ; 2644 : L -= 2; ; 2645 : ; 2646 : if (m == 0xE0 && L >= 5) { // JFIF APP0 segment ; 2647 : static const unsigned char tag[5] = { 'J','F','I','F','\0' }; ; 2648 : int ok = 1; ; 2649 : int i; ; 2650 : for (i = 0; i < 5; ++i) ; 2651 : if (stbi__get8(z->s) != tag[i]) ; 2652 : ok = 0; ; 2653 : L -= 5; ; 2654 : if (ok) ; 2655 : z->jfif = 1; ; 2656 : } ; 2657 : else if (m == 0xEE && L >= 12) { // Adobe APP14 segment ; 2658 : static const unsigned char tag[6] = { 'A','d','o','b','e','\0' }; ; 2659 : int ok = 1; ; 2660 : int i; ; 2661 : for (i = 0; i < 6; ++i) ; 2662 : if (stbi__get8(z->s) != tag[i]) ; 2663 : ok = 0; ; 2664 : L -= 6; ; 2665 : if (ok) { ; 2666 : stbi__get8(z->s); // version ; 2667 : stbi__get16be(z->s); // flags0 ; 2668 : stbi__get16be(z->s); // flags1 ; 2669 : z->app14_color_transform = stbi__get8(z->s); // color transform ; 2670 : L -= 6; ; 2671 : } ; 2672 : } ; 2673 : ; 2674 : stbi__skip(z->s, L); ; 2675 : return 1; ; 2676 : } ; 2677 : ; 2678 : return stbi__err("unknown marker", "Corrupt JPEG"); ; 2679 : } ; 2680 : ; 2681 : // after we see SOS ; 2682 : static int stbi__process_scan_header(stbi__jpeg* z) ; 2683 : { ; 2684 : int i; ; 2685 : int Ls = stbi__get16be(z->s); ; 2686 : z->scan_n = stbi__get8(z->s); ; 2687 : if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return stbi__err("bad SOS component count", "Corrupt JPEG"); ; 2688 : if (Ls != 6 + 2 * z->scan_n) return stbi__err("bad SOS len", "Corrupt JPEG"); ; 2689 : for (i = 0; i < z->scan_n; ++i) { ; 2690 : int id = stbi__get8(z->s), which; ; 2691 : int q = stbi__get8(z->s); ; 2692 : for (which = 0; which < z->s->img_n; ++which) ; 2693 : if (z->img_comp[which].id == id) ; 2694 : break; ; 2695 : if (which == z->s->img_n) return 0; // no match ; 2696 : z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff", "Corrupt JPEG"); ; 2697 : z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff", "Corrupt JPEG"); ; 2698 : z->order[i] = which; ; 2699 : } ; 2700 : ; 2701 : { ; 2702 : int aa; ; 2703 : z->spec_start = stbi__get8(z->s); ; 2704 : z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 ; 2705 : aa = stbi__get8(z->s); ; 2706 : z->succ_high = (aa >> 4); ; 2707 : z->succ_low = (aa & 15); ; 2708 : if (z->progressive) { ; 2709 : if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) ; 2710 : return stbi__err("bad SOS", "Corrupt JPEG"); ; 2711 : } ; 2712 : else { ; 2713 : if (z->spec_start != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2714 : if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS", "Corrupt JPEG"); ; 2715 : z->spec_end = 63; ; 2716 : } ; 2717 : } ; 2718 : ; 2719 : return 1; ; 2720 : } ; 2721 : ; 2722 : static int stbi__free_jpeg_components(stbi__jpeg* z, int ncomp, int why) ; 2723 : { ; 2724 : int i; ; 2725 : for (i = 0; i < ncomp; ++i) { ; 2726 : if (z->img_comp[i].raw_data) { ; 2727 : STBI_FREE(z->img_comp[i].raw_data); ; 2728 : z->img_comp[i].raw_data = NULL; ; 2729 : z->img_comp[i].data = NULL; ; 2730 : } ; 2731 : if (z->img_comp[i].raw_coeff) { ; 2732 : STBI_FREE(z->img_comp[i].raw_coeff); ; 2733 : z->img_comp[i].raw_coeff = 0; ; 2734 : z->img_comp[i].coeff = 0; ; 2735 : } ; 2736 : if (z->img_comp[i].linebuf) { ; 2737 : STBI_FREE(z->img_comp[i].linebuf); ; 2738 : z->img_comp[i].linebuf = NULL; ; 2739 : } ; 2740 : } ; 2741 : return why; ; 2742 : } ; 2743 : ; 2744 : static int stbi__process_frame_header(stbi__jpeg* z, int scan) ; 2745 : { ; 2746 : stbi__context* s = z->s; ; 2747 : int Lf, p, i, q, h_max = 1, v_max = 1, c; ; 2748 : Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len", "Corrupt JPEG"); // JPEG ; 2749 : p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline ; 2750 : s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG ; 2751 : s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width", "Corrupt JPEG"); // JPEG requires ; 2752 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2753 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 2754 : c = stbi__get8(s); ; 2755 : if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count", "Corrupt JPEG"); ; 2756 : s->img_n = c; ; 2757 : for (i = 0; i < c; ++i) { ; 2758 : z->img_comp[i].data = NULL; ; 2759 : z->img_comp[i].linebuf = NULL; ; 2760 : } ; 2761 : ; 2762 : if (Lf != 8 + 3 * s->img_n) return stbi__err("bad SOF len", "Corrupt JPEG"); ; 2763 : ; 2764 : z->rgb = 0; ; 2765 : for (i = 0; i < s->img_n; ++i) { ; 2766 : static const unsigned char rgb[3] = { 'R', 'G', 'B' }; ; 2767 : z->img_comp[i].id = stbi__get8(s); ; 2768 : if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ; 2769 : ++z->rgb; ; 2770 : q = stbi__get8(s); ; 2771 : z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H", "Corrupt JPEG"); ; 2772 : z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V", "Corrupt JPEG"); ; 2773 : z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ", "Corrupt JPEG"); ; 2774 : } ; 2775 : ; 2776 : if (scan != STBI__SCAN_load) return 1; ; 2777 : ; 2778 : if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); ; 2779 : ; 2780 : for (i = 0; i < s->img_n; ++i) { ; 2781 : if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; ; 2782 : if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; ; 2783 : } ; 2784 : ; 2785 : // check that plane subsampling factors are integer ratios; our resamplers can't deal with fractional ratios ; 2786 : // and I've never seen a non-corrupted JPEG file actually use them ; 2787 : for (i = 0; i < s->img_n; ++i) { ; 2788 : if (h_max % z->img_comp[i].h != 0) return stbi__err("bad H", "Corrupt JPEG"); ; 2789 : if (v_max % z->img_comp[i].v != 0) return stbi__err("bad V", "Corrupt JPEG"); ; 2790 : } ; 2791 : ; 2792 : // compute interleaved mcu info ; 2793 : z->img_h_max = h_max; ; 2794 : z->img_v_max = v_max; ; 2795 : z->img_mcu_w = h_max * 8; ; 2796 : z->img_mcu_h = v_max * 8; ; 2797 : // these sizes can't be more than 17 bits ; 2798 : z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; ; 2799 : z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; ; 2800 : ; 2801 : for (i = 0; i < s->img_n; ++i) { ; 2802 : // number of effective pixels (e.g. for non-interleaved MCU) ; 2803 : z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; ; 2804 : z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; ; 2805 : // to simplify generation, we'll allocate enough memory to decode ; 2806 : // the bogus oversized data from using interleaved MCUs and their ; 2807 : // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't ; 2808 : // discard the extra data until colorspace conversion ; 2809 : // ; 2810 : // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) ; 2811 : // so these muls can't overflow with 32-bit ints (which we require) ; 2812 : z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; ; 2813 : z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; ; 2814 : z->img_comp[i].coeff = 0; ; 2815 : z->img_comp[i].raw_coeff = 0; ; 2816 : z->img_comp[i].linebuf = NULL; ; 2817 : z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); ; 2818 : if (z->img_comp[i].raw_data == NULL) ; 2819 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2820 : // align blocks for idct using mmx/sse ; 2821 : z->img_comp[i].data = (stbi_uc*)(((size_t)z->img_comp[i].raw_data + 15) & ~15); ; 2822 : if (z->progressive) { ; 2823 : // w2, h2 are multiples of 8 (see above) ; 2824 : z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; ; 2825 : z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; ; 2826 : z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); ; 2827 : if (z->img_comp[i].raw_coeff == NULL) ; 2828 : return stbi__free_jpeg_components(z, i + 1, stbi__err("outofmem", "Out of memory")); ; 2829 : z->img_comp[i].coeff = (short*)(((size_t)z->img_comp[i].raw_coeff + 15) & ~15); ; 2830 : } ; 2831 : } ; 2832 : ; 2833 : return 1; ; 2834 : } ; 2835 : ; 2836 : // use comparisons since in some cases we handle more than one case (e.g. SOF) ; 2837 : #define stbi__DNL(x) ((x) == 0xdc) ; 2838 : #define stbi__SOI(x) ((x) == 0xd8) ; 2839 : #define stbi__EOI(x) ((x) == 0xd9) ; 2840 : #define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) ; 2841 : #define stbi__SOS(x) ((x) == 0xda) ; 2842 : ; 2843 : #define stbi__SOF_progressive(x) ((x) == 0xc2) ; 2844 : ; 2845 : static int stbi__decode_jpeg_header(stbi__jpeg* z, int scan) ; 2846 : { ; 2847 : int m; ; 2848 : z->jfif = 0; ; 2849 : z->app14_color_transform = -1; // valid values are 0,1,2 ; 2850 : z->marker = STBI__MARKER_none; // initialize cached marker to empty ; 2851 : m = stbi__get_marker(z); ; 2852 : if (!stbi__SOI(m)) return stbi__err("no SOI", "Corrupt JPEG"); ; 2853 : if (scan == STBI__SCAN_type) return 1; ; 2854 : m = stbi__get_marker(z); ; 2855 : while (!stbi__SOF(m)) { ; 2856 : if (!stbi__process_marker(z, m)) return 0; ; 2857 : m = stbi__get_marker(z); ; 2858 : while (m == STBI__MARKER_none) { ; 2859 : // some files have extra padding after their blocks, so ok, we'll scan ; 2860 : if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); ; 2861 : m = stbi__get_marker(z); ; 2862 : } ; 2863 : } ; 2864 : z->progressive = stbi__SOF_progressive(m); ; 2865 : if (!stbi__process_frame_header(z, scan)) return 0; ; 2866 : return 1; ; 2867 : } ; 2868 : ; 2869 : static int stbi__skip_jpeg_junk_at_end(stbi__jpeg* j) ; 2870 : { ; 2871 : // some JPEGs have junk at end, skip over it but if we find what looks ; 2872 : // like a valid marker, resume there ; 2873 : while (!stbi__at_eof(j->s)) { ; 2874 : int x = stbi__get8(j->s); ; 2875 : while (x == 255) { // might be a marker ; 2876 : if (stbi__at_eof(j->s)) return STBI__MARKER_none; ; 2877 : x = stbi__get8(j->s); ; 2878 : if (x != 0x00 && x != 0xff) { ; 2879 : // not a stuffed zero or lead-in to another marker, looks ; 2880 : // like an actual marker, return it ; 2881 : return x; ; 2882 : } ; 2883 : // stuffed zero has x=0 now which ends the loop, meaning we go ; 2884 : // back to regular scan loop. ; 2885 : // repeated 0xff keeps trying to read the next byte of the marker. ; 2886 : } ; 2887 : } ; 2888 : return STBI__MARKER_none; ; 2889 : } ; 2890 : ; 2891 : // decode image to YCbCr format ; 2892 : static int stbi__decode_jpeg_image(stbi__jpeg* j) ; 2893 : { ; 2894 : int m; ; 2895 : for (m = 0; m < 4; m++) { ; 2896 : j->img_comp[m].raw_data = NULL; ; 2897 : j->img_comp[m].raw_coeff = NULL; ; 2898 : } ; 2899 : j->restart_interval = 0; ; 2900 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; ; 2901 : m = stbi__get_marker(j); ; 2902 : while (!stbi__EOI(m)) { ; 2903 : if (stbi__SOS(m)) { ; 2904 : if (!stbi__process_scan_header(j)) return 0; ; 2905 : if (!stbi__parse_entropy_coded_data(j)) return 0; ; 2906 : if (j->marker == STBI__MARKER_none) { ; 2907 : j->marker = stbi__skip_jpeg_junk_at_end(j); ; 2908 : // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 ; 2909 : } ; 2910 : m = stbi__get_marker(j); ; 2911 : if (STBI__RESTART(m)) ; 2912 : m = stbi__get_marker(j); ; 2913 : } ; 2914 : else if (stbi__DNL(m)) { ; 2915 : int Ld = stbi__get16be(j->s); ; 2916 : stbi__uint32 NL = stbi__get16be(j->s); ; 2917 : if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); ; 2918 : if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); ; 2919 : m = stbi__get_marker(j); ; 2920 : } ; 2921 : else { ; 2922 : if (!stbi__process_marker(j, m)) return 1; ; 2923 : m = stbi__get_marker(j); ; 2924 : } ; 2925 : } ; 2926 : if (j->progressive) ; 2927 : stbi__jpeg_finish(j); ; 2928 : return 1; ; 2929 : } ; 2930 : ; 2931 : // static jfif-centered resampling (across block boundaries) ; 2932 : ; 2933 : typedef stbi_uc* (*resample_row_func)(stbi_uc* out, stbi_uc* in0, stbi_uc* in1, ; 2934 : int w, int hs); ; 2935 : ; 2936 : #define stbi__div4(x) ((stbi_uc) ((x) >> 2)) ; 2937 : ; 2938 : static stbi_uc* resample_row_1(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2939 : { ; 2940 : STBI_NOTUSED(out); ; 2941 : STBI_NOTUSED(in_far); ; 2942 : STBI_NOTUSED(w); ; 2943 : STBI_NOTUSED(hs); ; 2944 : return in_near; ; 2945 : } ; 2946 : ; 2947 : static stbi_uc* stbi__resample_row_v_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2948 : { ; 2949 : // need to generate two samples vertically for every one in input ; 2950 : int i; ; 2951 : STBI_NOTUSED(hs); ; 2952 : for (i = 0; i < w; ++i) ; 2953 : out[i] = stbi__div4(3 * in_near[i] + in_far[i] + 2); ; 2954 : return out; ; 2955 : } ; 2956 : ; 2957 : static stbi_uc* stbi__resample_row_h_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2958 : { ; 2959 : // need to generate two samples horizontally for every one in input ; 2960 : int i; ; 2961 : stbi_uc* input = in_near; ; 2962 : ; 2963 : if (w == 1) { ; 2964 : // if only one sample, can't do any interpolation ; 2965 : out[0] = out[1] = input[0]; ; 2966 : return out; ; 2967 : } ; 2968 : ; 2969 : out[0] = input[0]; ; 2970 : out[1] = stbi__div4(input[0] * 3 + input[1] + 2); ; 2971 : for (i = 1; i < w - 1; ++i) { ; 2972 : int n = 3 * input[i] + 2; ; 2973 : out[i * 2 + 0] = stbi__div4(n + input[i - 1]); ; 2974 : out[i * 2 + 1] = stbi__div4(n + input[i + 1]); ; 2975 : } ; 2976 : out[i * 2 + 0] = stbi__div4(input[w - 2] * 3 + input[w - 1] + 2); ; 2977 : out[i * 2 + 1] = input[w - 1]; ; 2978 : ; 2979 : STBI_NOTUSED(in_far); ; 2980 : STBI_NOTUSED(hs); ; 2981 : ; 2982 : return out; ; 2983 : } ; 2984 : ; 2985 : #define stbi__div16(x) ((stbi_uc) ((x) >> 4)) ; 2986 : ; 2987 : static stbi_uc* stbi__resample_row_hv_2(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 2988 : { ; 2989 : // need to generate 2x2 samples for every one in input ; 2990 : int i, t0, t1; ; 2991 : if (w == 1) { ; 2992 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 2993 : return out; ; 2994 : } ; 2995 : ; 2996 : t1 = 3 * in_near[0] + in_far[0]; ; 2997 : out[0] = stbi__div4(t1 + 2); ; 2998 : for (i = 1; i < w; ++i) { ; 2999 : t0 = t1; ; 3000 : t1 = 3 * in_near[i] + in_far[i]; ; 3001 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3002 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3003 : } ; 3004 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3005 : ; 3006 : STBI_NOTUSED(hs); ; 3007 : ; 3008 : return out; ; 3009 : } ; 3010 : ; 3011 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3012 : static stbi_uc* stbi__resample_row_hv_2_simd(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3013 : { ; 3014 : // need to generate 2x2 samples for every one in input ; 3015 : int i = 0, t0, t1; ; 3016 : ; 3017 : if (w == 1) { ; 3018 : out[0] = out[1] = stbi__div4(3 * in_near[0] + in_far[0] + 2); ; 3019 : return out; ; 3020 : } ; 3021 : ; 3022 : t1 = 3 * in_near[0] + in_far[0]; ; 3023 : // process groups of 8 pixels for as long as we can. ; 3024 : // note we can't handle the last pixel in a row in this loop ; 3025 : // because we need to handle the filter boundary conditions. ; 3026 : for (; i < ((w - 1) & ~7); i += 8) { ; 3027 : #if defined(STBI_SSE2) ; 3028 : // load and perform the vertical filtering pass ; 3029 : // this uses 3*x + y = 4*x + (y - x) ; 3030 : __m128i zero = _mm_setzero_si128(); ; 3031 : __m128i farb = _mm_loadl_epi64((__m128i*) (in_far + i)); ; 3032 : __m128i nearb = _mm_loadl_epi64((__m128i*) (in_near + i)); ; 3033 : __m128i farw = _mm_unpacklo_epi8(farb, zero); ; 3034 : __m128i nearw = _mm_unpacklo_epi8(nearb, zero); ; 3035 : __m128i diff = _mm_sub_epi16(farw, nearw); ; 3036 : __m128i nears = _mm_slli_epi16(nearw, 2); ; 3037 : __m128i curr = _mm_add_epi16(nears, diff); // current row ; 3038 : ; 3039 : // horizontal filter works the same based on shifted vers of current ; 3040 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3041 : // insert the previous pixel value (from t1). ; 3042 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3043 : // of next block of 8 pixels added in. ; 3044 : __m128i prv0 = _mm_slli_si128(curr, 2); ; 3045 : __m128i nxt0 = _mm_srli_si128(curr, 2); ; 3046 : __m128i prev = _mm_insert_epi16(prv0, t1, 0); ; 3047 : __m128i next = _mm_insert_epi16(nxt0, 3 * in_near[i + 8] + in_far[i + 8], 7); ; 3048 : ; 3049 : // horizontal filter, polyphase implementation since it's convenient: ; 3050 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3051 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3052 : // note the shared term. ; 3053 : __m128i bias = _mm_set1_epi16(8); ; 3054 : __m128i curs = _mm_slli_epi16(curr, 2); ; 3055 : __m128i prvd = _mm_sub_epi16(prev, curr); ; 3056 : __m128i nxtd = _mm_sub_epi16(next, curr); ; 3057 : __m128i curb = _mm_add_epi16(curs, bias); ; 3058 : __m128i even = _mm_add_epi16(prvd, curb); ; 3059 : __m128i odd = _mm_add_epi16(nxtd, curb); ; 3060 : ; 3061 : // interleave even and odd pixels, then undo scaling. ; 3062 : __m128i int0 = _mm_unpacklo_epi16(even, odd); ; 3063 : __m128i int1 = _mm_unpackhi_epi16(even, odd); ; 3064 : __m128i de0 = _mm_srli_epi16(int0, 4); ; 3065 : __m128i de1 = _mm_srli_epi16(int1, 4); ; 3066 : ; 3067 : // pack and write output ; 3068 : __m128i outv = _mm_packus_epi16(de0, de1); ; 3069 : _mm_storeu_si128((__m128i*) (out + i * 2), outv); ; 3070 : #elif defined(STBI_NEON) ; 3071 : // load and perform the vertical filtering pass ; 3072 : // this uses 3*x + y = 4*x + (y - x) ; 3073 : uint8x8_t farb = vld1_u8(in_far + i); ; 3074 : uint8x8_t nearb = vld1_u8(in_near + i); ; 3075 : int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); ; 3076 : int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); ; 3077 : int16x8_t curr = vaddq_s16(nears, diff); // current row ; 3078 : ; 3079 : // horizontal filter works the same based on shifted vers of current ; 3080 : // row. "prev" is current row shifted right by 1 pixel; we need to ; 3081 : // insert the previous pixel value (from t1). ; 3082 : // "next" is current row shifted left by 1 pixel, with first pixel ; 3083 : // of next block of 8 pixels added in. ; 3084 : int16x8_t prv0 = vextq_s16(curr, curr, 7); ; 3085 : int16x8_t nxt0 = vextq_s16(curr, curr, 1); ; 3086 : int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); ; 3087 : int16x8_t next = vsetq_lane_s16(3 * in_near[i + 8] + in_far[i + 8], nxt0, 7); ; 3088 : ; 3089 : // horizontal filter, polyphase implementation since it's convenient: ; 3090 : // even pixels = 3*cur + prev = cur*4 + (prev - cur) ; 3091 : // odd pixels = 3*cur + next = cur*4 + (next - cur) ; 3092 : // note the shared term. ; 3093 : int16x8_t curs = vshlq_n_s16(curr, 2); ; 3094 : int16x8_t prvd = vsubq_s16(prev, curr); ; 3095 : int16x8_t nxtd = vsubq_s16(next, curr); ; 3096 : int16x8_t even = vaddq_s16(curs, prvd); ; 3097 : int16x8_t odd = vaddq_s16(curs, nxtd); ; 3098 : ; 3099 : // undo scaling and round, then store with even/odd phases interleaved ; 3100 : uint8x8x2_t o; ; 3101 : o.val[0] = vqrshrun_n_s16(even, 4); ; 3102 : o.val[1] = vqrshrun_n_s16(odd, 4); ; 3103 : vst2_u8(out + i * 2, o); ; 3104 : #endif ; 3105 : ; 3106 : // "previous" value for next iter ; 3107 : t1 = 3 * in_near[i + 7] + in_far[i + 7]; ; 3108 : } ; 3109 : ; 3110 : t0 = t1; ; 3111 : t1 = 3 * in_near[i] + in_far[i]; ; 3112 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3113 : ; 3114 : for (++i; i < w; ++i) { ; 3115 : t0 = t1; ; 3116 : t1 = 3 * in_near[i] + in_far[i]; ; 3117 : out[i * 2 - 1] = stbi__div16(3 * t0 + t1 + 8); ; 3118 : out[i * 2] = stbi__div16(3 * t1 + t0 + 8); ; 3119 : } ; 3120 : out[w * 2 - 1] = stbi__div4(t1 + 2); ; 3121 : ; 3122 : STBI_NOTUSED(hs); ; 3123 : ; 3124 : return out; ; 3125 : } ; 3126 : #endif ; 3127 : ; 3128 : static stbi_uc* stbi__resample_row_generic(stbi_uc* out, stbi_uc* in_near, stbi_uc* in_far, int w, int hs) ; 3129 : { ; 3130 : // resample with nearest-neighbor ; 3131 : int i, j; ; 3132 : STBI_NOTUSED(in_far); ; 3133 : for (i = 0; i < w; ++i) ; 3134 : for (j = 0; j < hs; ++j) ; 3135 : out[i * hs + j] = in_near[i]; ; 3136 : return out; ; 3137 : } ; 3138 : ; 3139 : // this is a reduced-precision calculation of YCbCr-to-RGB introduced ; 3140 : // to make sure the code produces the same results in both SIMD and scalar ; 3141 : #define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) ; 3142 : static void stbi__YCbCr_to_RGB_row(stbi_uc* out, const stbi_uc* y, const stbi_uc* pcb, const stbi_uc* pcr, int count, int step) ; 3143 : { ; 3144 : int i; ; 3145 : for (i = 0; i < count; ++i) { ; 3146 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3147 : int r, g, b; ; 3148 : int cr = pcr[i] - 128; ; 3149 : int cb = pcb[i] - 128; ; 3150 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3151 : g = y_fixed + (cr * -stbi__float2fixed(0.71414f)) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3152 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3153 : r >>= 20; ; 3154 : g >>= 20; ; 3155 : b >>= 20; ; 3156 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3157 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3158 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3159 : out[0] = (stbi_uc)r; ; 3160 : out[1] = (stbi_uc)g; ; 3161 : out[2] = (stbi_uc)b; ; 3162 : out[3] = 255; ; 3163 : out += step; ; 3164 : } ; 3165 : } ; 3166 : ; 3167 : #if defined(STBI_SSE2) || defined(STBI_NEON) ; 3168 : static void stbi__YCbCr_to_RGB_simd(stbi_uc* out, stbi_uc const* y, stbi_uc const* pcb, stbi_uc const* pcr, int count, int step) ; 3169 : { ; 3170 : int i = 0; ; 3171 : ; 3172 : #ifdef STBI_SSE2 ; 3173 : // step == 3 is pretty ugly on the final interleave, and i'm not convinced ; 3174 : // it's useful in practice (you wouldn't use it for textures, for example). ; 3175 : // so just accelerate step == 4 case. ; 3176 : if (step == 4) { ; 3177 : // this is a fairly straightforward implementation and not super-optimized. ; 3178 : __m128i signflip = _mm_set1_epi8(-0x80); ; 3179 : __m128i cr_const0 = _mm_set1_epi16((short)(1.40200f * 4096.0f + 0.5f)); ; 3180 : __m128i cr_const1 = _mm_set1_epi16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3181 : __m128i cb_const0 = _mm_set1_epi16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3182 : __m128i cb_const1 = _mm_set1_epi16((short)(1.77200f * 4096.0f + 0.5f)); ; 3183 : __m128i y_bias = _mm_set1_epi8((char)(unsigned char)128); ; 3184 : __m128i xw = _mm_set1_epi16(255); // alpha channel ; 3185 : ; 3186 : for (; i + 7 < count; i += 8) { ; 3187 : // load ; 3188 : __m128i y_bytes = _mm_loadl_epi64((__m128i*) (y + i)); ; 3189 : __m128i cr_bytes = _mm_loadl_epi64((__m128i*) (pcr + i)); ; 3190 : __m128i cb_bytes = _mm_loadl_epi64((__m128i*) (pcb + i)); ; 3191 : __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 ; 3192 : __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 ; 3193 : ; 3194 : // unpack to short (and left-shift cr, cb by 8) ; 3195 : __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); ; 3196 : __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); ; 3197 : __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); ; 3198 : ; 3199 : // color transform ; 3200 : __m128i yws = _mm_srli_epi16(yw, 4); ; 3201 : __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); ; 3202 : __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); ; 3203 : __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); ; 3204 : __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); ; 3205 : __m128i rws = _mm_add_epi16(cr0, yws); ; 3206 : __m128i gwt = _mm_add_epi16(cb0, yws); ; 3207 : __m128i bws = _mm_add_epi16(yws, cb1); ; 3208 : __m128i gws = _mm_add_epi16(gwt, cr1); ; 3209 : ; 3210 : // descale ; 3211 : __m128i rw = _mm_srai_epi16(rws, 4); ; 3212 : __m128i bw = _mm_srai_epi16(bws, 4); ; 3213 : __m128i gw = _mm_srai_epi16(gws, 4); ; 3214 : ; 3215 : // back to byte, set up for transpose ; 3216 : __m128i brb = _mm_packus_epi16(rw, bw); ; 3217 : __m128i gxb = _mm_packus_epi16(gw, xw); ; 3218 : ; 3219 : // transpose to interleave channels ; 3220 : __m128i t0 = _mm_unpacklo_epi8(brb, gxb); ; 3221 : __m128i t1 = _mm_unpackhi_epi8(brb, gxb); ; 3222 : __m128i o0 = _mm_unpacklo_epi16(t0, t1); ; 3223 : __m128i o1 = _mm_unpackhi_epi16(t0, t1); ; 3224 : ; 3225 : // store ; 3226 : _mm_storeu_si128((__m128i*) (out + 0), o0); ; 3227 : _mm_storeu_si128((__m128i*) (out + 16), o1); ; 3228 : out += 32; ; 3229 : } ; 3230 : } ; 3231 : #endif ; 3232 : ; 3233 : #ifdef STBI_NEON ; 3234 : // in this version, step=3 support would be easy to add. but is there demand? ; 3235 : if (step == 4) { ; 3236 : // this is a fairly straightforward implementation and not super-optimized. ; 3237 : uint8x8_t signflip = vdup_n_u8(0x80); ; 3238 : int16x8_t cr_const0 = vdupq_n_s16((short)(1.40200f * 4096.0f + 0.5f)); ; 3239 : int16x8_t cr_const1 = vdupq_n_s16(-(short)(0.71414f * 4096.0f + 0.5f)); ; 3240 : int16x8_t cb_const0 = vdupq_n_s16(-(short)(0.34414f * 4096.0f + 0.5f)); ; 3241 : int16x8_t cb_const1 = vdupq_n_s16((short)(1.77200f * 4096.0f + 0.5f)); ; 3242 : ; 3243 : for (; i + 7 < count; i += 8) { ; 3244 : // load ; 3245 : uint8x8_t y_bytes = vld1_u8(y + i); ; 3246 : uint8x8_t cr_bytes = vld1_u8(pcr + i); ; 3247 : uint8x8_t cb_bytes = vld1_u8(pcb + i); ; 3248 : int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); ; 3249 : int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); ; 3250 : ; 3251 : // expand to s16 ; 3252 : int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); ; 3253 : int16x8_t crw = vshll_n_s8(cr_biased, 7); ; 3254 : int16x8_t cbw = vshll_n_s8(cb_biased, 7); ; 3255 : ; 3256 : // color transform ; 3257 : int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); ; 3258 : int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); ; 3259 : int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); ; 3260 : int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); ; 3261 : int16x8_t rws = vaddq_s16(yws, cr0); ; 3262 : int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); ; 3263 : int16x8_t bws = vaddq_s16(yws, cb1); ; 3264 : ; 3265 : // undo scaling, round, convert to byte ; 3266 : uint8x8x4_t o; ; 3267 : o.val[0] = vqrshrun_n_s16(rws, 4); ; 3268 : o.val[1] = vqrshrun_n_s16(gws, 4); ; 3269 : o.val[2] = vqrshrun_n_s16(bws, 4); ; 3270 : o.val[3] = vdup_n_u8(255); ; 3271 : ; 3272 : // store, interleaving r/g/b/a ; 3273 : vst4_u8(out, o); ; 3274 : out += 8 * 4; ; 3275 : } ; 3276 : } ; 3277 : #endif ; 3278 : ; 3279 : for (; i < count; ++i) { ; 3280 : int y_fixed = (y[i] << 20) + (1 << 19); // rounding ; 3281 : int r, g, b; ; 3282 : int cr = pcr[i] - 128; ; 3283 : int cb = pcb[i] - 128; ; 3284 : r = y_fixed + cr * stbi__float2fixed(1.40200f); ; 3285 : g = y_fixed + cr * -stbi__float2fixed(0.71414f) + ((cb * -stbi__float2fixed(0.34414f)) & 0xffff0000); ; 3286 : b = y_fixed + cb * stbi__float2fixed(1.77200f); ; 3287 : r >>= 20; ; 3288 : g >>= 20; ; 3289 : b >>= 20; ; 3290 : if ((unsigned)r > 255) { if (r < 0) r = 0; else r = 255; } ; 3291 : if ((unsigned)g > 255) { if (g < 0) g = 0; else g = 255; } ; 3292 : if ((unsigned)b > 255) { if (b < 0) b = 0; else b = 255; } ; 3293 : out[0] = (stbi_uc)r; ; 3294 : out[1] = (stbi_uc)g; ; 3295 : out[2] = (stbi_uc)b; ; 3296 : out[3] = 255; ; 3297 : out += step; ; 3298 : } ; 3299 : } ; 3300 : #endif ; 3301 : ; 3302 : // set up the kernels ; 3303 : static void stbi__setup_jpeg(stbi__jpeg* j) ; 3304 : { ; 3305 : j->idct_block_kernel = stbi__idct_block; ; 3306 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; ; 3307 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; ; 3308 : ; 3309 : #ifdef STBI_SSE2 ; 3310 : if (stbi__sse2_available()) { ; 3311 : j->idct_block_kernel = stbi__idct_simd; ; 3312 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3313 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3314 : } ; 3315 : #endif ; 3316 : ; 3317 : #ifdef STBI_NEON ; 3318 : j->idct_block_kernel = stbi__idct_simd; ; 3319 : j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; ; 3320 : j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; ; 3321 : #endif ; 3322 : } ; 3323 : ; 3324 : // clean up the temporary component buffers ; 3325 : static void stbi__cleanup_jpeg(stbi__jpeg* j) ; 3326 : { ; 3327 : stbi__free_jpeg_components(j, j->s->img_n, 0); ; 3328 : } ; 3329 : ; 3330 : typedef struct ; 3331 : { ; 3332 : resample_row_func resample; ; 3333 : stbi_uc* line0, * line1; ; 3334 : int hs, vs; // expansion factor in each axis ; 3335 : int w_lores; // horizontal pixels pre-expansion ; 3336 : int ystep; // how far through vertical expansion we are ; 3337 : int ypos; // which pre-expansion row we're on ; 3338 : } stbi__resample; ; 3339 : ; 3340 : // fast 0..255 * 0..255 => 0..255 rounded multiplication ; 3341 : static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) ; 3342 : { ; 3343 : unsigned int t = x * y + 128; ; 3344 : return (stbi_uc)((t + (t >> 8)) >> 8); ; 3345 : } ; 3346 : ; 3347 : static stbi_uc* load_jpeg_image(stbi__jpeg* z, int* out_x, int* out_y, int* comp, int req_comp) ; 3348 : { ; 3349 : int n, decode_n, is_rgb; ; 3350 : z->s->img_n = 0; // make stbi__cleanup_jpeg safe ; 3351 : ; 3352 : // validate req_comp ; 3353 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 3354 : ; 3355 : // load a jpeg image from whichever source, but leave in YCbCr format ; 3356 : if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } ; 3357 : ; 3358 : // determine actual number of components to generate ; 3359 : n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; ; 3360 : ; 3361 : is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); ; 3362 : ; 3363 : if (z->s->img_n == 3 && n < 3 && !is_rgb) ; 3364 : decode_n = 1; ; 3365 : else ; 3366 : decode_n = z->s->img_n; ; 3367 : ; 3368 : // nothing to do if no components requested; check this now to avoid ; 3369 : // accessing uninitialized coutput[0] later ; 3370 : if (decode_n <= 0) { stbi__cleanup_jpeg(z); return NULL; } ; 3371 : ; 3372 : // resample and color-convert ; 3373 : { ; 3374 : int k; ; 3375 : unsigned int i, j; ; 3376 : stbi_uc* output; ; 3377 : stbi_uc* coutput[4] = { NULL, NULL, NULL, NULL }; ; 3378 : ; 3379 : stbi__resample res_comp[4]; ; 3380 : ; 3381 : for (k = 0; k < decode_n; ++k) { ; 3382 : stbi__resample* r = &res_comp[k]; ; 3383 : ; 3384 : // allocate line buffer big enough for upsampling off the edges ; 3385 : // with upsample factor of 4 ; 3386 : z->img_comp[k].linebuf = (stbi_uc*)stbi__malloc(z->s->img_x + 3); ; 3387 : if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3388 : ; 3389 : r->hs = z->img_h_max / z->img_comp[k].h; ; 3390 : r->vs = z->img_v_max / z->img_comp[k].v; ; 3391 : r->ystep = r->vs >> 1; ; 3392 : r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; ; 3393 : r->ypos = 0; ; 3394 : r->line0 = r->line1 = z->img_comp[k].data; ; 3395 : ; 3396 : if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; ; 3397 : else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; ; 3398 : else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; ; 3399 : else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; ; 3400 : else r->resample = stbi__resample_row_generic; ; 3401 : } ; 3402 : ; 3403 : // can't error after this so, this is safe ; 3404 : output = (stbi_uc*)stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); ; 3405 : if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } ; 3406 : ; 3407 : // now go ahead and resample ; 3408 : for (j = 0; j < z->s->img_y; ++j) { ; 3409 : stbi_uc* out = output + n * z->s->img_x * j; ; 3410 : for (k = 0; k < decode_n; ++k) { ; 3411 : stbi__resample* r = &res_comp[k]; ; 3412 : int y_bot = r->ystep >= (r->vs >> 1); ; 3413 : coutput[k] = r->resample(z->img_comp[k].linebuf, ; 3414 : y_bot ? r->line1 : r->line0, ; 3415 : y_bot ? r->line0 : r->line1, ; 3416 : r->w_lores, r->hs); ; 3417 : if (++r->ystep >= r->vs) { ; 3418 : r->ystep = 0; ; 3419 : r->line0 = r->line1; ; 3420 : if (++r->ypos < z->img_comp[k].y) ; 3421 : r->line1 += z->img_comp[k].w2; ; 3422 : } ; 3423 : } ; 3424 : if (n >= 3) { ; 3425 : stbi_uc* y = coutput[0]; ; 3426 : if (z->s->img_n == 3) { ; 3427 : if (is_rgb) { ; 3428 : for (i = 0; i < z->s->img_x; ++i) { ; 3429 : out[0] = y[i]; ; 3430 : out[1] = coutput[1][i]; ; 3431 : out[2] = coutput[2][i]; ; 3432 : out[3] = 255; ; 3433 : out += n; ; 3434 : } ; 3435 : } ; 3436 : else { ; 3437 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3438 : } ; 3439 : } ; 3440 : else if (z->s->img_n == 4) { ; 3441 : if (z->app14_color_transform == 0) { // CMYK ; 3442 : for (i = 0; i < z->s->img_x; ++i) { ; 3443 : stbi_uc m = coutput[3][i]; ; 3444 : out[0] = stbi__blinn_8x8(coutput[0][i], m); ; 3445 : out[1] = stbi__blinn_8x8(coutput[1][i], m); ; 3446 : out[2] = stbi__blinn_8x8(coutput[2][i], m); ; 3447 : out[3] = 255; ; 3448 : out += n; ; 3449 : } ; 3450 : } ; 3451 : else if (z->app14_color_transform == 2) { // YCCK ; 3452 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3453 : for (i = 0; i < z->s->img_x; ++i) { ; 3454 : stbi_uc m = coutput[3][i]; ; 3455 : out[0] = stbi__blinn_8x8(255 - out[0], m); ; 3456 : out[1] = stbi__blinn_8x8(255 - out[1], m); ; 3457 : out[2] = stbi__blinn_8x8(255 - out[2], m); ; 3458 : out += n; ; 3459 : } ; 3460 : } ; 3461 : else { // YCbCr + alpha? Ignore the fourth channel for now ; 3462 : z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); ; 3463 : } ; 3464 : } ; 3465 : else ; 3466 : for (i = 0; i < z->s->img_x; ++i) { ; 3467 : out[0] = out[1] = out[2] = y[i]; ; 3468 : out[3] = 255; // not used if n==3 ; 3469 : out += n; ; 3470 : } ; 3471 : } ; 3472 : else { ; 3473 : if (is_rgb) { ; 3474 : if (n == 1) ; 3475 : for (i = 0; i < z->s->img_x; ++i) ; 3476 : *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3477 : else { ; 3478 : for (i = 0; i < z->s->img_x; ++i, out += 2) { ; 3479 : out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); ; 3480 : out[1] = 255; ; 3481 : } ; 3482 : } ; 3483 : } ; 3484 : else if (z->s->img_n == 4 && z->app14_color_transform == 0) { ; 3485 : for (i = 0; i < z->s->img_x; ++i) { ; 3486 : stbi_uc m = coutput[3][i]; ; 3487 : stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); ; 3488 : stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); ; 3489 : stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); ; 3490 : out[0] = stbi__compute_y(r, g, b); ; 3491 : out[1] = 255; ; 3492 : out += n; ; 3493 : } ; 3494 : } ; 3495 : else if (z->s->img_n == 4 && z->app14_color_transform == 2) { ; 3496 : for (i = 0; i < z->s->img_x; ++i) { ; 3497 : out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); ; 3498 : out[1] = 255; ; 3499 : out += n; ; 3500 : } ; 3501 : } ; 3502 : else { ; 3503 : stbi_uc* y = coutput[0]; ; 3504 : if (n == 1) ; 3505 : for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; ; 3506 : else ; 3507 : for (i = 0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } ; 3508 : } ; 3509 : } ; 3510 : } ; 3511 : stbi__cleanup_jpeg(z); ; 3512 : *out_x = z->s->img_x; ; 3513 : *out_y = z->s->img_y; ; 3514 : if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output ; 3515 : return output; ; 3516 : } ; 3517 : } ; 3518 : ; 3519 : static void* stbi__jpeg_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 3520 : { ; 3521 : unsigned char* result; ; 3522 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3523 : if (!j) return stbi__errpuc("outofmem", "Out of memory"); ; 3524 : memset(j, 0, sizeof(stbi__jpeg)); ; 3525 : STBI_NOTUSED(ri); ; 3526 : j->s = s; ; 3527 : stbi__setup_jpeg(j); ; 3528 : result = load_jpeg_image(j, x, y, comp, req_comp); ; 3529 : STBI_FREE(j); ; 3530 : return result; ; 3531 : } ; 3532 : ; 3533 : static int stbi__jpeg_test(stbi__context* s) ; 3534 : { ; 3535 : int r; ; 3536 : stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); ; 3537 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3538 : memset(j, 0, sizeof(stbi__jpeg)); ; 3539 : j->s = s; ; 3540 : stbi__setup_jpeg(j); ; 3541 : r = stbi__decode_jpeg_header(j, STBI__SCAN_type); ; 3542 : stbi__rewind(s); ; 3543 : STBI_FREE(j); ; 3544 : return r; ; 3545 : } ; 3546 : ; 3547 : static int stbi__jpeg_info_raw(stbi__jpeg* j, int* x, int* y, int* comp) ; 3548 : { ; 3549 : if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { ; 3550 : stbi__rewind(j->s); ; 3551 : return 0; ; 3552 : } ; 3553 : if (x) *x = j->s->img_x; ; 3554 : if (y) *y = j->s->img_y; ; 3555 : if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; ; 3556 : return 1; ; 3557 : } ; 3558 : ; 3559 : static int stbi__jpeg_info(stbi__context* s, int* x, int* y, int* comp) ; 3560 : { ; 3561 : int result; ; 3562 : stbi__jpeg* j = (stbi__jpeg*)(stbi__malloc(sizeof(stbi__jpeg))); ; 3563 : if (!j) return stbi__err("outofmem", "Out of memory"); ; 3564 : memset(j, 0, sizeof(stbi__jpeg)); ; 3565 : j->s = s; ; 3566 : result = stbi__jpeg_info_raw(j, x, y, comp); ; 3567 : STBI_FREE(j); ; 3568 : return result; ; 3569 : } ; 3570 : #endif ; 3571 : ; 3572 : // public domain zlib decode v0.2 Sean Barrett 2006-11-18 ; 3573 : // simple implementation ; 3574 : // - all input must be provided in an upfront buffer ; 3575 : // - all output is written to a single output buffer (can malloc/realloc) ; 3576 : // performance ; 3577 : // - fast huffman ; 3578 : ; 3579 : #ifndef STBI_NO_ZLIB ; 3580 : ; 3581 : // fast-way is faster to check than jpeg huffman, but slow way is slower ; 3582 : #define STBI__ZFAST_BITS 9 // accelerate all cases in default tables ; 3583 : #define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) ; 3584 : #define STBI__ZNSYMS 288 // number of symbols in literal/length alphabet ; 3585 : ; 3586 : // zlib-style huffman encoding ; 3587 : // (jpegs packs from left, zlib from right, so can't share code) ; 3588 : typedef struct ; 3589 : { ; 3590 : stbi__uint16 fast[1 << STBI__ZFAST_BITS]; ; 3591 : stbi__uint16 firstcode[16]; ; 3592 : int maxcode[17]; ; 3593 : stbi__uint16 firstsymbol[16]; ; 3594 : stbi_uc size[STBI__ZNSYMS]; ; 3595 : stbi__uint16 value[STBI__ZNSYMS]; ; 3596 : } stbi__zhuffman; ; 3597 : ; 3598 : stbi_inline static int stbi__bitreverse16(int n) ; 3599 : { ; 3600 : n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); ; 3601 : n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); ; 3602 : n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); ; 3603 : n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); ; 3604 : return n; ; 3605 : } ; 3606 : ; 3607 : stbi_inline static int stbi__bit_reverse(int v, int bits) ; 3608 : { ; 3609 : STBI_ASSERT(bits <= 16); ; 3610 : // to bit reverse n bits, reverse 16 and shift ; 3611 : // e.g. 11 bits, bit reverse and shift away 5 ; 3612 : return stbi__bitreverse16(v) >> (16 - bits); ; 3613 : } ; 3614 : ; 3615 : static int stbi__zbuild_huffman(stbi__zhuffman* z, const stbi_uc* sizelist, int num) ; 3616 : { ; 3617 : int i, k = 0; ; 3618 : int code, next_code[16], sizes[17]; ; 3619 : ; 3620 : // DEFLATE spec for generating codes ; 3621 : memset(sizes, 0, sizeof(sizes)); ; 3622 : memset(z->fast, 0, sizeof(z->fast)); ; 3623 : for (i = 0; i < num; ++i) ; 3624 : ++sizes[sizelist[i]]; ; 3625 : sizes[0] = 0; ; 3626 : for (i = 1; i < 16; ++i) ; 3627 : if (sizes[i] > (1 << i)) ; 3628 : return stbi__err("bad sizes", "Corrupt PNG"); ; 3629 : code = 0; ; 3630 : for (i = 1; i < 16; ++i) { ; 3631 : next_code[i] = code; ; 3632 : z->firstcode[i] = (stbi__uint16)code; ; 3633 : z->firstsymbol[i] = (stbi__uint16)k; ; 3634 : code = (code + sizes[i]); ; 3635 : if (sizes[i]) ; 3636 : if (code - 1 >= (1 << i)) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3637 : z->maxcode[i] = code << (16 - i); // preshift for inner loop ; 3638 : code <<= 1; ; 3639 : k += sizes[i]; ; 3640 : } ; 3641 : z->maxcode[16] = 0x10000; // sentinel ; 3642 : for (i = 0; i < num; ++i) { ; 3643 : int s = sizelist[i]; ; 3644 : if (s) { ; 3645 : int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; ; 3646 : stbi__uint16 fastv = (stbi__uint16)((s << 9) | i); ; 3647 : z->size[c] = (stbi_uc)s; ; 3648 : z->value[c] = (stbi__uint16)i; ; 3649 : if (s <= STBI__ZFAST_BITS) { ; 3650 : int j = stbi__bit_reverse(next_code[s], s); ; 3651 : while (j < (1 << STBI__ZFAST_BITS)) { ; 3652 : z->fast[j] = fastv; ; 3653 : j += (1 << s); ; 3654 : } ; 3655 : } ; 3656 : ++next_code[s]; ; 3657 : } ; 3658 : } ; 3659 : return 1; ; 3660 : } ; 3661 : ; 3662 : // zlib-from-memory implementation for PNG reading ; 3663 : // because PNG allows splitting the zlib stream arbitrarily, ; 3664 : // and it's annoying structurally to have PNG call ZLIB call PNG, ; 3665 : // we require PNG read all the IDATs and combine them into a single ; 3666 : // memory buffer ; 3667 : ; 3668 : typedef struct ; 3669 : { ; 3670 : stbi_uc* zbuffer, * zbuffer_end; ; 3671 : int num_bits; ; 3672 : stbi__uint32 code_buffer; ; 3673 : ; 3674 : char* zout; ; 3675 : char* zout_start; ; 3676 : char* zout_end; ; 3677 : int z_expandable; ; 3678 : ; 3679 : stbi__zhuffman z_length, z_distance; ; 3680 : } stbi__zbuf; ; 3681 : ; 3682 : stbi_inline static int stbi__zeof(stbi__zbuf* z) ; 3683 : { ; 3684 : return (z->zbuffer >= z->zbuffer_end); ; 3685 : } ; 3686 : ; 3687 : stbi_inline static stbi_uc stbi__zget8(stbi__zbuf* z) ; 3688 : { ; 3689 : return stbi__zeof(z) ? 0 : *z->zbuffer++; ; 3690 : } ; 3691 : ; 3692 : static void stbi__fill_bits(stbi__zbuf* z) ; 3693 : { ; 3694 : do { ; 3695 : if (z->code_buffer >= (1U << z->num_bits)) { ; 3696 : z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */ ; 3697 : return; ; 3698 : } ; 3699 : z->code_buffer |= (unsigned int)stbi__zget8(z) << z->num_bits; ; 3700 : z->num_bits += 8; ; 3701 : } while (z->num_bits <= 24); ; 3702 : } ; 3703 : ; 3704 : stbi_inline static unsigned int stbi__zreceive(stbi__zbuf* z, int n) ; 3705 : { ; 3706 : unsigned int k; ; 3707 : if (z->num_bits < n) stbi__fill_bits(z); ; 3708 : k = z->code_buffer & ((1 << n) - 1); ; 3709 : z->code_buffer >>= n; ; 3710 : z->num_bits -= n; ; 3711 : return k; ; 3712 : } ; 3713 : ; 3714 : static int stbi__zhuffman_decode_slowpath(stbi__zbuf* a, stbi__zhuffman* z) ; 3715 : { ; 3716 : int b, s, k; ; 3717 : // not resolved by fast table, so compute it the slow way ; 3718 : // use jpeg approach, which requires MSbits at top ; 3719 : k = stbi__bit_reverse(a->code_buffer, 16); ; 3720 : for (s = STBI__ZFAST_BITS + 1; ; ++s) ; 3721 : if (k < z->maxcode[s]) ; 3722 : break; ; 3723 : if (s >= 16) return -1; // invalid code! ; 3724 : // code size is s, so: ; 3725 : b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; ; 3726 : if (b >= STBI__ZNSYMS) return -1; // some data was corrupt somewhere! ; 3727 : if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. ; 3728 : a->code_buffer >>= s; ; 3729 : a->num_bits -= s; ; 3730 : return z->value[b]; ; 3731 : } ; 3732 : ; 3733 : stbi_inline static int stbi__zhuffman_decode(stbi__zbuf* a, stbi__zhuffman* z) ; 3734 : { ; 3735 : int b, s; ; 3736 : if (a->num_bits < 16) { ; 3737 : if (stbi__zeof(a)) { ; 3738 : return -1; /* report error for unexpected end of data. */ ; 3739 : } ; 3740 : stbi__fill_bits(a); ; 3741 : } ; 3742 : b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; ; 3743 : if (b) { ; 3744 : s = b >> 9; ; 3745 : a->code_buffer >>= s; ; 3746 : a->num_bits -= s; ; 3747 : return b & 511; ; 3748 : } ; 3749 : return stbi__zhuffman_decode_slowpath(a, z); ; 3750 : } ; 3751 : ; 3752 : static int stbi__zexpand(stbi__zbuf* z, char* zout, int n) // need to make room for n bytes ; 3753 : { ; 3754 : char* q; ; 3755 : unsigned int cur, limit, old_limit; ; 3756 : z->zout = zout; ; 3757 : if (!z->z_expandable) return stbi__err("output buffer limit", "Corrupt PNG"); ; 3758 : cur = (unsigned int)(z->zout - z->zout_start); ; 3759 : limit = old_limit = (unsigned)(z->zout_end - z->zout_start); ; 3760 : if (UINT_MAX - cur < (unsigned)n) return stbi__err("outofmem", "Out of memory"); ; 3761 : while (cur + n > limit) { ; 3762 : if (limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory"); ; 3763 : limit *= 2; ; 3764 : } ; 3765 : q = (char*)STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); ; 3766 : STBI_NOTUSED(old_limit); ; 3767 : if (q == NULL) return stbi__err("outofmem", "Out of memory"); ; 3768 : z->zout_start = q; ; 3769 : z->zout = q + cur; ; 3770 : z->zout_end = q + limit; ; 3771 : return 1; ; 3772 : } ; 3773 : ; 3774 : static const int stbi__zlength_base[31] = { ; 3775 : 3,4,5,6,7,8,9,10,11,13, ; 3776 : 15,17,19,23,27,31,35,43,51,59, ; 3777 : 67,83,99,115,131,163,195,227,258,0,0 }; ; 3778 : ; 3779 : static const int stbi__zlength_extra[31] = ; 3780 : { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; ; 3781 : ; 3782 : static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, ; 3783 : 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0 }; ; 3784 : ; 3785 : static const int stbi__zdist_extra[32] = ; 3786 : { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; ; 3787 : ; 3788 : static int stbi__parse_huffman_block(stbi__zbuf* a) ; 3789 : { ; 3790 : char* zout = a->zout; ; 3791 : for (;;) { ; 3792 : int z = stbi__zhuffman_decode(a, &a->z_length); ; 3793 : if (z < 256) { ; 3794 : if (z < 0) return stbi__err("bad huffman code", "Corrupt PNG"); // error in huffman codes ; 3795 : if (zout >= a->zout_end) { ; 3796 : if (!stbi__zexpand(a, zout, 1)) return 0; ; 3797 : zout = a->zout; ; 3798 : } ; 3799 : *zout++ = (char)z; ; 3800 : } ; 3801 : else { ; 3802 : stbi_uc* p; ; 3803 : int len, dist; ; 3804 : if (z == 256) { ; 3805 : a->zout = zout; ; 3806 : return 1; ; 3807 : } ; 3808 : if (z >= 286) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data ; 3809 : z -= 257; ; 3810 : len = stbi__zlength_base[z]; ; 3811 : if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); ; 3812 : z = stbi__zhuffman_decode(a, &a->z_distance); ; 3813 : if (z < 0 || z >= 30) return stbi__err("bad huffman code", "Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data ; 3814 : dist = stbi__zdist_base[z]; ; 3815 : if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); ; 3816 : if (zout - a->zout_start < dist) return stbi__err("bad dist", "Corrupt PNG"); ; 3817 : if (zout + len > a->zout_end) { ; 3818 : if (!stbi__zexpand(a, zout, len)) return 0; ; 3819 : zout = a->zout; ; 3820 : } ; 3821 : p = (stbi_uc*)(zout - dist); ; 3822 : if (dist == 1) { // run of one byte; common in images. ; 3823 : stbi_uc v = *p; ; 3824 : if (len) { do *zout++ = v; while (--len); } ; 3825 : } ; 3826 : else { ; 3827 : if (len) { do *zout++ = *p++; while (--len); } ; 3828 : } ; 3829 : } ; 3830 : } ; 3831 : } ; 3832 : ; 3833 : static int stbi__compute_huffman_codes(stbi__zbuf* a) ; 3834 : { ; 3835 : static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; ; 3836 : stbi__zhuffman z_codelength; ; 3837 : stbi_uc lencodes[286 + 32 + 137];//padding for maximum single op ; 3838 : stbi_uc codelength_sizes[19]; ; 3839 : int i, n; ; 3840 : ; 3841 : int hlit = stbi__zreceive(a, 5) + 257; ; 3842 : int hdist = stbi__zreceive(a, 5) + 1; ; 3843 : int hclen = stbi__zreceive(a, 4) + 4; ; 3844 : int ntot = hlit + hdist; ; 3845 : ; 3846 : memset(codelength_sizes, 0, sizeof(codelength_sizes)); ; 3847 : for (i = 0; i < hclen; ++i) { ; 3848 : int s = stbi__zreceive(a, 3); ; 3849 : codelength_sizes[length_dezigzag[i]] = (stbi_uc)s; ; 3850 : } ; 3851 : if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; ; 3852 : ; 3853 : n = 0; ; 3854 : while (n < ntot) { ; 3855 : int c = stbi__zhuffman_decode(a, &z_codelength); ; 3856 : if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3857 : if (c < 16) ; 3858 : lencodes[n++] = (stbi_uc)c; ; 3859 : else { ; 3860 : stbi_uc fill = 0; ; 3861 : if (c == 16) { ; 3862 : c = stbi__zreceive(a, 2) + 3; ; 3863 : if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3864 : fill = lencodes[n - 1]; ; 3865 : } ; 3866 : else if (c == 17) { ; 3867 : c = stbi__zreceive(a, 3) + 3; ; 3868 : } ; 3869 : else if (c == 18) { ; 3870 : c = stbi__zreceive(a, 7) + 11; ; 3871 : } ; 3872 : else { ; 3873 : return stbi__err("bad codelengths", "Corrupt PNG"); ; 3874 : } ; 3875 : if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3876 : memset(lencodes + n, fill, c); ; 3877 : n += c; ; 3878 : } ; 3879 : } ; 3880 : if (n != ntot) return stbi__err("bad codelengths", "Corrupt PNG"); ; 3881 : if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; ; 3882 : if (!stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; ; 3883 : return 1; ; 3884 : } ; 3885 : ; 3886 : static int stbi__parse_uncompressed_block(stbi__zbuf* a) ; 3887 : { ; 3888 : stbi_uc header[4]; ; 3889 : int len, nlen, k; ; 3890 : if (a->num_bits & 7) ; 3891 : stbi__zreceive(a, a->num_bits & 7); // discard ; 3892 : // drain the bit-packed data into header ; 3893 : k = 0; ; 3894 : while (a->num_bits > 0) { ; 3895 : header[k++] = (stbi_uc)(a->code_buffer & 255); // suppress MSVC run-time check ; 3896 : a->code_buffer >>= 8; ; 3897 : a->num_bits -= 8; ; 3898 : } ; 3899 : if (a->num_bits < 0) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3900 : // now fill header the normal way ; 3901 : while (k < 4) ; 3902 : header[k++] = stbi__zget8(a); ; 3903 : len = header[1] * 256 + header[0]; ; 3904 : nlen = header[3] * 256 + header[2]; ; 3905 : if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt", "Corrupt PNG"); ; 3906 : if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer", "Corrupt PNG"); ; 3907 : if (a->zout + len > a->zout_end) ; 3908 : if (!stbi__zexpand(a, a->zout, len)) return 0; ; 3909 : memcpy(a->zout, a->zbuffer, len); ; 3910 : a->zbuffer += len; ; 3911 : a->zout += len; ; 3912 : return 1; ; 3913 : } ; 3914 : ; 3915 : static int stbi__parse_zlib_header(stbi__zbuf* a) ; 3916 : { ; 3917 : int cmf = stbi__zget8(a); ; 3918 : int cm = cmf & 15; ; 3919 : /* int cinfo = cmf >> 4; */ ; 3920 : int flg = stbi__zget8(a); ; 3921 : if (stbi__zeof(a)) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3922 : if ((cmf * 256 + flg) % 31 != 0) return stbi__err("bad zlib header", "Corrupt PNG"); // zlib spec ; 3923 : if (flg & 32) return stbi__err("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png ; 3924 : if (cm != 8) return stbi__err("bad compression", "Corrupt PNG"); // DEFLATE required for png ; 3925 : // window = 1 << (8 + cinfo)... but who cares, we fully buffer output ; 3926 : return 1; ; 3927 : } ; 3928 : ; 3929 : static const stbi_uc stbi__zdefault_length[STBI__ZNSYMS] = ; 3930 : { ; 3931 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3932 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3933 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3934 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ; 3935 : 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3936 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3937 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3938 : 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, ; 3939 : 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 ; 3940 : }; ; 3941 : static const stbi_uc stbi__zdefault_distance[32] = ; 3942 : { ; 3943 : 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 ; 3944 : }; ; 3945 : /* ; 3946 : Init algorithm: ; 3947 : { ; 3948 : int i; // use <= to match clearly with spec ; 3949 : for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; ; 3950 : for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; ; 3951 : for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; ; 3952 : for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; ; 3953 : ; 3954 : for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; ; 3955 : } ; 3956 : */ ; 3957 : ; 3958 : static int stbi__parse_zlib(stbi__zbuf* a, int parse_header) ; 3959 : { ; 3960 : int final, type; ; 3961 : if (parse_header) ; 3962 : if (!stbi__parse_zlib_header(a)) return 0; ; 3963 : a->num_bits = 0; ; 3964 : a->code_buffer = 0; ; 3965 : do { ; 3966 : final = stbi__zreceive(a, 1); ; 3967 : type = stbi__zreceive(a, 2); ; 3968 : if (type == 0) { ; 3969 : if (!stbi__parse_uncompressed_block(a)) return 0; ; 3970 : } ; 3971 : else if (type == 3) { ; 3972 : return 0; ; 3973 : } ; 3974 : else { ; 3975 : if (type == 1) { ; 3976 : // use fixed code lengths ; 3977 : if (!stbi__zbuild_huffman(&a->z_length, stbi__zdefault_length, STBI__ZNSYMS)) return 0; ; 3978 : if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; ; 3979 : } ; 3980 : else { ; 3981 : if (!stbi__compute_huffman_codes(a)) return 0; ; 3982 : } ; 3983 : if (!stbi__parse_huffman_block(a)) return 0; ; 3984 : } ; 3985 : } while (!final); ; 3986 : return 1; ; 3987 : } ; 3988 : ; 3989 : static int stbi__do_zlib(stbi__zbuf* a, char* obuf, int olen, int exp, int parse_header) ; 3990 : { ; 3991 : a->zout_start = obuf; ; 3992 : a->zout = obuf; ; 3993 : a->zout_end = obuf + olen; ; 3994 : a->z_expandable = exp; ; 3995 : ; 3996 : return stbi__parse_zlib(a, parse_header); ; 3997 : } ; 3998 : ; 3999 : STBIDEF char* stbi_zlib_decode_malloc_guesssize(const char* buffer, int len, int initial_size, int* outlen) ; 4000 : { ; 4001 : stbi__zbuf a; ; 4002 : char* p = (char*)stbi__malloc(initial_size); ; 4003 : if (p == NULL) return NULL; ; 4004 : a.zbuffer = (stbi_uc*)buffer; ; 4005 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4006 : if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { ; 4007 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4008 : return a.zout_start; ; 4009 : } ; 4010 : else { ; 4011 : STBI_FREE(a.zout_start); ; 4012 : return NULL; ; 4013 : } ; 4014 : } ; 4015 : ; 4016 : STBIDEF char* stbi_zlib_decode_malloc(char const* buffer, int len, int* outlen) ; 4017 : { ; 4018 : return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); ; 4019 : } ; 4020 : ; 4021 : STBIDEF char* stbi_zlib_decode_malloc_guesssize_headerflag(const char* buffer, int len, int initial_size, int* outlen, int parse_header) ; 4022 : { ; 4023 : stbi__zbuf a; ; 4024 : char* p = (char*)stbi__malloc(initial_size); ; 4025 : if (p == NULL) return NULL; ; 4026 : a.zbuffer = (stbi_uc*)buffer; ; 4027 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4028 : if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { ; 4029 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4030 : return a.zout_start; ; 4031 : } ; 4032 : else { ; 4033 : STBI_FREE(a.zout_start); ; 4034 : return NULL; ; 4035 : } ; 4036 : } ; 4037 : ; 4038 : STBIDEF int stbi_zlib_decode_buffer(char* obuffer, int olen, char const* ibuffer, int ilen) ; 4039 : { ; 4040 : stbi__zbuf a; ; 4041 : a.zbuffer = (stbi_uc*)ibuffer; ; 4042 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4043 : if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) ; 4044 : return (int)(a.zout - a.zout_start); ; 4045 : else ; 4046 : return -1; ; 4047 : } ; 4048 : ; 4049 : STBIDEF char* stbi_zlib_decode_noheader_malloc(char const* buffer, int len, int* outlen) ; 4050 : { ; 4051 : stbi__zbuf a; ; 4052 : char* p = (char*)stbi__malloc(16384); ; 4053 : if (p == NULL) return NULL; ; 4054 : a.zbuffer = (stbi_uc*)buffer; ; 4055 : a.zbuffer_end = (stbi_uc*)buffer + len; ; 4056 : if (stbi__do_zlib(&a, p, 16384, 1, 0)) { ; 4057 : if (outlen) *outlen = (int)(a.zout - a.zout_start); ; 4058 : return a.zout_start; ; 4059 : } ; 4060 : else { ; 4061 : STBI_FREE(a.zout_start); ; 4062 : return NULL; ; 4063 : } ; 4064 : } ; 4065 : ; 4066 : STBIDEF int stbi_zlib_decode_noheader_buffer(char* obuffer, int olen, const char* ibuffer, int ilen) ; 4067 : { ; 4068 : stbi__zbuf a; ; 4069 : a.zbuffer = (stbi_uc*)ibuffer; ; 4070 : a.zbuffer_end = (stbi_uc*)ibuffer + ilen; ; 4071 : if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) ; 4072 : return (int)(a.zout - a.zout_start); ; 4073 : else ; 4074 : return -1; ; 4075 : } ; 4076 : #endif ; 4077 : ; 4078 : // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 ; 4079 : // simple implementation ; 4080 : // - only 8-bit samples ; 4081 : // - no CRC checking ; 4082 : // - allocates lots of intermediate memory ; 4083 : // - avoids problem of streaming data between subsystems ; 4084 : // - avoids explicit window management ; 4085 : // performance ; 4086 : // - uses stb_zlib, a PD zlib implementation with fast huffman decoding ; 4087 : ; 4088 : #ifndef STBI_NO_PNG ; 4089 : typedef struct ; 4090 : { ; 4091 : stbi__uint32 length; ; 4092 : stbi__uint32 type; ; 4093 : } stbi__pngchunk; ; 4094 : ; 4095 : static stbi__pngchunk stbi__get_chunk_header(stbi__context* s) ; 4096 : { ; 4097 : stbi__pngchunk c; ; 4098 : c.length = stbi__get32be(s); ; 4099 : c.type = stbi__get32be(s); ; 4100 : return c; ; 4101 : } ; 4102 : ; 4103 : static int stbi__check_png_header(stbi__context* s) ; 4104 : { ; 4105 : static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; ; 4106 : int i; ; 4107 : for (i = 0; i < 8; ++i) ; 4108 : if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig", "Not a PNG"); ; 4109 : return 1; ; 4110 : } ; 4111 : ; 4112 : typedef struct ; 4113 : { ; 4114 : stbi__context* s; ; 4115 : stbi_uc* idata, * expanded, * out; ; 4116 : int depth; ; 4117 : } stbi__png; ; 4118 : ; 4119 : enum { ; 4120 : STBI__F_none = 0, ; 4121 : STBI__F_sub = 1, ; 4122 : STBI__F_up = 2, ; 4123 : STBI__F_avg = 3, ; 4124 : STBI__F_paeth = 4, ; 4125 : // synthetic filters used for first scanline to avoid needing a dummy row of 0s ; 4126 : STBI__F_avg_first, ; 4127 : STBI__F_paeth_first ; 4128 : }; ; 4129 : ; 4130 : static stbi_uc first_row_filter[5] = ; 4131 : { ; 4132 : STBI__F_none, ; 4133 : STBI__F_sub, ; 4134 : STBI__F_none, ; 4135 : STBI__F_avg_first, ; 4136 : STBI__F_paeth_first ; 4137 : }; ; 4138 : ; 4139 : static int stbi__paeth(int a, int b, int c) ; 4140 : { ; 4141 : int p = a + b - c; ; 4142 : int pa = abs(p - a); ; 4143 : int pb = abs(p - b); ; 4144 : int pc = abs(p - c); ; 4145 : if (pa <= pb && pa <= pc) return a; ; 4146 : if (pb <= pc) return b; ; 4147 : return c; ; 4148 : } ; 4149 : ; 4150 : static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; ; 4151 : ; 4152 : // create the png data from post-deflated data ; 4153 : static int stbi__create_png_image_raw(stbi__png* a, stbi_uc* raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) ; 4154 : { ; 4155 : int bytes = (depth == 16 ? 2 : 1); ; 4156 : stbi__context* s = a->s; ; 4157 : stbi__uint32 i, j, stride = x * out_n * bytes; ; 4158 : stbi__uint32 img_len, img_width_bytes; ; 4159 : int k; ; 4160 : int img_n = s->img_n; // copy it into a local for later ; 4161 : ; 4162 : int output_bytes = out_n * bytes; ; 4163 : int filter_bytes = img_n * bytes; ; 4164 : int width = x; ; 4165 : ; 4166 : STBI_ASSERT(out_n == s->img_n || out_n == s->img_n + 1); ; 4167 : a->out = (stbi_uc*)stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into ; 4168 : if (!a->out) return stbi__err("outofmem", "Out of memory"); ; 4169 : ; 4170 : if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); ; 4171 : img_width_bytes = (((img_n * x * depth) + 7) >> 3); ; 4172 : img_len = (img_width_bytes + 1) * y; ; 4173 : ; 4174 : // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, ; 4175 : // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), ; 4176 : // so just check for raw_len < img_len always. ; 4177 : if (raw_len < img_len) return stbi__err("not enough pixels", "Corrupt PNG"); ; 4178 : ; 4179 : for (j = 0; j < y; ++j) { ; 4180 : stbi_uc* cur = a->out + stride * j; ; 4181 : stbi_uc* prior; ; 4182 : int filter = *raw++; ; 4183 : ; 4184 : if (filter > 4) ; 4185 : return stbi__err("invalid filter", "Corrupt PNG"); ; 4186 : ; 4187 : if (depth < 8) { ; 4188 : if (img_width_bytes > x) return stbi__err("invalid width", "Corrupt PNG"); ; 4189 : cur += x * out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place ; 4190 : filter_bytes = 1; ; 4191 : width = img_width_bytes; ; 4192 : } ; 4193 : prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above ; 4194 : ; 4195 : // if first row, use special filter that doesn't sample previous row ; 4196 : if (j == 0) filter = first_row_filter[filter]; ; 4197 : ; 4198 : // handle first byte explicitly ; 4199 : for (k = 0; k < filter_bytes; ++k) { ; 4200 : switch (filter) { ; 4201 : case STBI__F_none: cur[k] = raw[k]; break; ; 4202 : case STBI__F_sub: cur[k] = raw[k]; break; ; 4203 : case STBI__F_up: cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; ; 4204 : case STBI__F_avg: cur[k] = STBI__BYTECAST(raw[k] + (prior[k] >> 1)); break; ; 4205 : case STBI__F_paeth: cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0, prior[k], 0)); break; ; 4206 : case STBI__F_avg_first: cur[k] = raw[k]; break; ; 4207 : case STBI__F_paeth_first: cur[k] = raw[k]; break; ; 4208 : } ; 4209 : } ; 4210 : ; 4211 : if (depth == 8) { ; 4212 : if (img_n != out_n) ; 4213 : cur[img_n] = 255; // first pixel ; 4214 : raw += img_n; ; 4215 : cur += out_n; ; 4216 : prior += out_n; ; 4217 : } ; 4218 : else if (depth == 16) { ; 4219 : if (img_n != out_n) { ; 4220 : cur[filter_bytes] = 255; // first pixel top byte ; 4221 : cur[filter_bytes + 1] = 255; // first pixel bottom byte ; 4222 : } ; 4223 : raw += filter_bytes; ; 4224 : cur += output_bytes; ; 4225 : prior += output_bytes; ; 4226 : } ; 4227 : else { ; 4228 : raw += 1; ; 4229 : cur += 1; ; 4230 : prior += 1; ; 4231 : } ; 4232 : ; 4233 : // this is a little gross, so that we don't switch per-pixel or per-component ; 4234 : if (depth < 8 || img_n == out_n) { ; 4235 : int nk = (width - 1) * filter_bytes; ; 4236 : #define STBI__CASE(f) \ ; 4237 : case f: \ ; 4238 : for (k=0; k < nk; ++k) ; 4239 : switch (filter) { ; 4240 : // "none" filter turns into a memcpy here; make that explicit. ; 4241 : case STBI__F_none: memcpy(cur, raw, nk); break; ; 4242 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - filter_bytes]); } break; ; 4243 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4244 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - filter_bytes]) >> 1)); } break; ; 4245 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], prior[k], prior[k - filter_bytes])); } break; ; 4246 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - filter_bytes] >> 1)); } break; ; 4247 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - filter_bytes], 0, 0)); } break; ; 4248 : } ; 4249 : #undef STBI__CASE ; 4250 : raw += nk; ; 4251 : } ; 4252 : else { ; 4253 : STBI_ASSERT(img_n + 1 == out_n); ; 4254 : #define STBI__CASE(f) \ ; 4255 : case f: \ ; 4256 : for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ ; 4257 : for (k=0; k < filter_bytes; ++k) ; 4258 : switch (filter) { ; 4259 : STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; ; 4260 : STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k - output_bytes]); } break; ; 4261 : STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; ; 4262 : STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k - output_bytes]) >> 1)); } break; ; 4263 : STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], prior[k], prior[k - output_bytes])); } break; ; 4264 : STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k - output_bytes] >> 1)); } break; ; 4265 : STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k - output_bytes], 0, 0)); } break; ; 4266 : } ; 4267 : #undef STBI__CASE ; 4268 : ; 4269 : // the loop above sets the high byte of the pixels' alpha, but for ; 4270 : // 16 bit png files we also need the low byte set. we'll do that here. ; 4271 : if (depth == 16) { ; 4272 : cur = a->out + stride * j; // start at the beginning of the row again ; 4273 : for (i = 0; i < x; ++i, cur += output_bytes) { ; 4274 : cur[filter_bytes + 1] = 255; ; 4275 : } ; 4276 : } ; 4277 : } ; 4278 : } ; 4279 : ; 4280 : // we make a separate pass to expand bits to pixels; for performance, ; 4281 : // this could run two scanlines behind the above code, so it won't ; 4282 : // intefere with filtering but will still be in the cache. ; 4283 : if (depth < 8) { ; 4284 : for (j = 0; j < y; ++j) { ; 4285 : stbi_uc* cur = a->out + stride * j; ; 4286 : stbi_uc* in = a->out + stride * j + x * out_n - img_width_bytes; ; 4287 : // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit ; 4288 : // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop ; 4289 : stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range ; 4290 : ; 4291 : // note that the final byte might overshoot and write more data than desired. ; 4292 : // we can allocate enough data that this never writes out of memory, but it ; 4293 : // could also overwrite the next scanline. can it overwrite non-empty data ; 4294 : // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. ; 4295 : // so we need to explicitly clamp the final ones ; 4296 : ; 4297 : if (depth == 4) { ; 4298 : for (k = x * img_n; k >= 2; k -= 2, ++in) { ; 4299 : *cur++ = scale * ((*in >> 4)); ; 4300 : *cur++ = scale * ((*in) & 0x0f); ; 4301 : } ; 4302 : if (k > 0) *cur++ = scale * ((*in >> 4)); ; 4303 : } ; 4304 : else if (depth == 2) { ; 4305 : for (k = x * img_n; k >= 4; k -= 4, ++in) { ; 4306 : *cur++ = scale * ((*in >> 6)); ; 4307 : *cur++ = scale * ((*in >> 4) & 0x03); ; 4308 : *cur++ = scale * ((*in >> 2) & 0x03); ; 4309 : *cur++ = scale * ((*in) & 0x03); ; 4310 : } ; 4311 : if (k > 0) *cur++ = scale * ((*in >> 6)); ; 4312 : if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); ; 4313 : if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); ; 4314 : } ; 4315 : else if (depth == 1) { ; 4316 : for (k = x * img_n; k >= 8; k -= 8, ++in) { ; 4317 : *cur++ = scale * ((*in >> 7)); ; 4318 : *cur++ = scale * ((*in >> 6) & 0x01); ; 4319 : *cur++ = scale * ((*in >> 5) & 0x01); ; 4320 : *cur++ = scale * ((*in >> 4) & 0x01); ; 4321 : *cur++ = scale * ((*in >> 3) & 0x01); ; 4322 : *cur++ = scale * ((*in >> 2) & 0x01); ; 4323 : *cur++ = scale * ((*in >> 1) & 0x01); ; 4324 : *cur++ = scale * ((*in) & 0x01); ; 4325 : } ; 4326 : if (k > 0) *cur++ = scale * ((*in >> 7)); ; 4327 : if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); ; 4328 : if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); ; 4329 : if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); ; 4330 : if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); ; 4331 : if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); ; 4332 : if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); ; 4333 : } ; 4334 : if (img_n != out_n) { ; 4335 : int q; ; 4336 : // insert alpha = 255 ; 4337 : cur = a->out + stride * j; ; 4338 : if (img_n == 1) { ; 4339 : for (q = x - 1; q >= 0; --q) { ; 4340 : cur[q * 2 + 1] = 255; ; 4341 : cur[q * 2 + 0] = cur[q]; ; 4342 : } ; 4343 : } ; 4344 : else { ; 4345 : STBI_ASSERT(img_n == 3); ; 4346 : for (q = x - 1; q >= 0; --q) { ; 4347 : cur[q * 4 + 3] = 255; ; 4348 : cur[q * 4 + 2] = cur[q * 3 + 2]; ; 4349 : cur[q * 4 + 1] = cur[q * 3 + 1]; ; 4350 : cur[q * 4 + 0] = cur[q * 3 + 0]; ; 4351 : } ; 4352 : } ; 4353 : } ; 4354 : } ; 4355 : } ; 4356 : else if (depth == 16) { ; 4357 : // force the image data from big-endian to platform-native. ; 4358 : // this is done in a separate pass due to the decoding relying ; 4359 : // on the data being untouched, but could probably be done ; 4360 : // per-line during decode if care is taken. ; 4361 : stbi_uc* cur = a->out; ; 4362 : stbi__uint16* cur16 = (stbi__uint16*)cur; ; 4363 : ; 4364 : for (i = 0; i < x * y * out_n; ++i, cur16++, cur += 2) { ; 4365 : *cur16 = (cur[0] << 8) | cur[1]; ; 4366 : } ; 4367 : } ; 4368 : ; 4369 : return 1; ; 4370 : } ; 4371 : ; 4372 : static int stbi__create_png_image(stbi__png* a, stbi_uc* image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) ; 4373 : { ; 4374 : int bytes = (depth == 16 ? 2 : 1); ; 4375 : int out_bytes = out_n * bytes; ; 4376 : stbi_uc* final; ; 4377 : int p; ; 4378 : if (!interlaced) ; 4379 : return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); ; 4380 : ; 4381 : // de-interlacing ; 4382 : final = (stbi_uc*)stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); ; 4383 : if (!final) return stbi__err("outofmem", "Out of memory"); ; 4384 : for (p = 0; p < 7; ++p) { ; 4385 : int xorig[] = { 0,4,0,2,0,1,0 }; ; 4386 : int yorig[] = { 0,0,4,0,2,0,1 }; ; 4387 : int xspc[] = { 8,8,4,4,2,2,1 }; ; 4388 : int yspc[] = { 8,8,8,4,4,2,2 }; ; 4389 : int i, j, x, y; ; 4390 : // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 ; 4391 : x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; ; 4392 : y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; ; 4393 : if (x && y) { ; 4394 : stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; ; 4395 : if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { ; 4396 : STBI_FREE(final); ; 4397 : return 0; ; 4398 : } ; 4399 : for (j = 0; j < y; ++j) { ; 4400 : for (i = 0; i < x; ++i) { ; 4401 : int out_y = j * yspc[p] + yorig[p]; ; 4402 : int out_x = i * xspc[p] + xorig[p]; ; 4403 : memcpy(final + out_y * a->s->img_x * out_bytes + out_x * out_bytes, ; 4404 : a->out + (j * x + i) * out_bytes, out_bytes); ; 4405 : } ; 4406 : } ; 4407 : STBI_FREE(a->out); ; 4408 : image_data += img_len; ; 4409 : image_data_len -= img_len; ; 4410 : } ; 4411 : } ; 4412 : a->out = final; ; 4413 : ; 4414 : return 1; ; 4415 : } ; 4416 : ; 4417 : static int stbi__compute_transparency(stbi__png* z, stbi_uc tc[3], int out_n) ; 4418 : { ; 4419 : stbi__context* s = z->s; ; 4420 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4421 : stbi_uc* p = z->out; ; 4422 : ; 4423 : // compute color-based transparency, assuming we've ; 4424 : // already got 255 as the alpha value in the output ; 4425 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4426 : ; 4427 : if (out_n == 2) { ; 4428 : for (i = 0; i < pixel_count; ++i) { ; 4429 : p[1] = (p[0] == tc[0] ? 0 : 255); ; 4430 : p += 2; ; 4431 : } ; 4432 : } ; 4433 : else { ; 4434 : for (i = 0; i < pixel_count; ++i) { ; 4435 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4436 : p[3] = 0; ; 4437 : p += 4; ; 4438 : } ; 4439 : } ; 4440 : return 1; ; 4441 : } ; 4442 : ; 4443 : static int stbi__compute_transparency16(stbi__png* z, stbi__uint16 tc[3], int out_n) ; 4444 : { ; 4445 : stbi__context* s = z->s; ; 4446 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4447 : stbi__uint16* p = (stbi__uint16*)z->out; ; 4448 : ; 4449 : // compute color-based transparency, assuming we've ; 4450 : // already got 65535 as the alpha value in the output ; 4451 : STBI_ASSERT(out_n == 2 || out_n == 4); ; 4452 : ; 4453 : if (out_n == 2) { ; 4454 : for (i = 0; i < pixel_count; ++i) { ; 4455 : p[1] = (p[0] == tc[0] ? 0 : 65535); ; 4456 : p += 2; ; 4457 : } ; 4458 : } ; 4459 : else { ; 4460 : for (i = 0; i < pixel_count; ++i) { ; 4461 : if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) ; 4462 : p[3] = 0; ; 4463 : p += 4; ; 4464 : } ; 4465 : } ; 4466 : return 1; ; 4467 : } ; 4468 : ; 4469 : static int stbi__expand_png_palette(stbi__png* a, stbi_uc* palette, int len, int pal_img_n) ; 4470 : { ; 4471 : stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; ; 4472 : stbi_uc* p, * temp_out, * orig = a->out; ; 4473 : ; 4474 : p = (stbi_uc*)stbi__malloc_mad2(pixel_count, pal_img_n, 0); ; 4475 : if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4476 : ; 4477 : // between here and free(out) below, exitting would leak ; 4478 : temp_out = p; ; 4479 : ; 4480 : if (pal_img_n == 3) { ; 4481 : for (i = 0; i < pixel_count; ++i) { ; 4482 : int n = orig[i] * 4; ; 4483 : p[0] = palette[n]; ; 4484 : p[1] = palette[n + 1]; ; 4485 : p[2] = palette[n + 2]; ; 4486 : p += 3; ; 4487 : } ; 4488 : } ; 4489 : else { ; 4490 : for (i = 0; i < pixel_count; ++i) { ; 4491 : int n = orig[i] * 4; ; 4492 : p[0] = palette[n]; ; 4493 : p[1] = palette[n + 1]; ; 4494 : p[2] = palette[n + 2]; ; 4495 : p[3] = palette[n + 3]; ; 4496 : p += 4; ; 4497 : } ; 4498 : } ; 4499 : STBI_FREE(a->out); ; 4500 : a->out = temp_out; ; 4501 : ; 4502 : STBI_NOTUSED(len); ; 4503 : ; 4504 : return 1; ; 4505 : } ; 4506 : ; 4507 : static int stbi__unpremultiply_on_load_global = 0; ; 4508 : static int stbi__de_iphone_flag_global = 0; ; 4509 : ; 4510 : STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) ; 4511 : { ; 4512 : stbi__unpremultiply_on_load_global = flag_true_if_should_unpremultiply; ; 4513 : } ; 4514 : ; 4515 : STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) ; 4516 : { ; 4517 : stbi__de_iphone_flag_global = flag_true_if_should_convert; ; 4518 : } ; 4519 : ; 4520 : #ifndef STBI_THREAD_LOCAL ; 4521 : #define stbi__unpremultiply_on_load stbi__unpremultiply_on_load_global ; 4522 : #define stbi__de_iphone_flag stbi__de_iphone_flag_global ; 4523 : #else ; 4524 : static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set; ; 4525 : static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set; ; 4526 : ; 4527 : STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply) ; 4528 : { ; 4529 : stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply; ; 4530 : stbi__unpremultiply_on_load_set = 1; ; 4531 : } ; 4532 : ; 4533 : STBIDEF void stbi_convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert) ; 4534 : { ; 4535 : stbi__de_iphone_flag_local = flag_true_if_should_convert; ; 4536 : stbi__de_iphone_flag_set = 1; ; 4537 : } ; 4538 : ; 4539 : #define stbi__unpremultiply_on_load (stbi__unpremultiply_on_load_set \ ; 4540 : ? stbi__unpremultiply_on_load_local \ ; 4541 : : stbi__unpremultiply_on_load_global) ; 4542 : #define stbi__de_iphone_flag (stbi__de_iphone_flag_set \ ; 4543 : ? stbi__de_iphone_flag_local \ ; 4544 : : stbi__de_iphone_flag_global) ; 4545 : #endif // STBI_THREAD_LOCAL ; 4546 : ; 4547 : static void stbi__de_iphone(stbi__png* z) ; 4548 : { ; 4549 : stbi__context* s = z->s; ; 4550 : stbi__uint32 i, pixel_count = s->img_x * s->img_y; ; 4551 : stbi_uc* p = z->out; ; 4552 : ; 4553 : if (s->img_out_n == 3) { // convert bgr to rgb ; 4554 : for (i = 0; i < pixel_count; ++i) { ; 4555 : stbi_uc t = p[0]; ; 4556 : p[0] = p[2]; ; 4557 : p[2] = t; ; 4558 : p += 3; ; 4559 : } ; 4560 : } ; 4561 : else { ; 4562 : STBI_ASSERT(s->img_out_n == 4); ; 4563 : if (stbi__unpremultiply_on_load) { ; 4564 : // convert bgr to rgb and unpremultiply ; 4565 : for (i = 0; i < pixel_count; ++i) { ; 4566 : stbi_uc a = p[3]; ; 4567 : stbi_uc t = p[0]; ; 4568 : if (a) { ; 4569 : stbi_uc half = a / 2; ; 4570 : p[0] = (p[2] * 255 + half) / a; ; 4571 : p[1] = (p[1] * 255 + half) / a; ; 4572 : p[2] = (t * 255 + half) / a; ; 4573 : } ; 4574 : else { ; 4575 : p[0] = p[2]; ; 4576 : p[2] = t; ; 4577 : } ; 4578 : p += 4; ; 4579 : } ; 4580 : } ; 4581 : else { ; 4582 : // convert bgr to rgb ; 4583 : for (i = 0; i < pixel_count; ++i) { ; 4584 : stbi_uc t = p[0]; ; 4585 : p[0] = p[2]; ; 4586 : p[2] = t; ; 4587 : p += 4; ; 4588 : } ; 4589 : } ; 4590 : } ; 4591 : } ; 4592 : ; 4593 : #define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) ; 4594 : ; 4595 : static int stbi__parse_png_file(stbi__png* z, int scan, int req_comp) ; 4596 : { ; 4597 : stbi_uc palette[1024], pal_img_n = 0; ; 4598 : stbi_uc has_trans = 0, tc[3] = { 0 }; ; 4599 : stbi__uint16 tc16[3]; ; 4600 : stbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; ; 4601 : int first = 1, k, interlace = 0, color = 0, is_iphone = 0; ; 4602 : stbi__context* s = z->s; ; 4603 : ; 4604 : z->expanded = NULL; ; 4605 : z->idata = NULL; ; 4606 : z->out = NULL; ; 4607 : ; 4608 : if (!stbi__check_png_header(s)) return 0; ; 4609 : ; 4610 : if (scan == STBI__SCAN_type) return 1; ; 4611 : ; 4612 : for (;;) { ; 4613 : stbi__pngchunk c = stbi__get_chunk_header(s); ; 4614 : switch (c.type) { ; 4615 : case STBI__PNG_TYPE('C', 'g', 'B', 'I'): ; 4616 : is_iphone = 1; ; 4617 : stbi__skip(s, c.length); ; 4618 : break; ; 4619 : case STBI__PNG_TYPE('I', 'H', 'D', 'R'): { ; 4620 : int comp, filter; ; 4621 : if (!first) return stbi__err("multiple IHDR", "Corrupt PNG"); ; 4622 : first = 0; ; 4623 : if (c.length != 13) return stbi__err("bad IHDR len", "Corrupt PNG"); ; 4624 : s->img_x = stbi__get32be(s); ; 4625 : s->img_y = stbi__get32be(s); ; 4626 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4627 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 4628 : z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only", "PNG not supported: 1/2/4/8/16-bit only"); ; 4629 : color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype", "Corrupt PNG"); ; 4630 : if (color == 3 && z->depth == 16) return stbi__err("bad ctype", "Corrupt PNG"); ; 4631 : if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype", "Corrupt PNG"); ; 4632 : comp = stbi__get8(s); if (comp) return stbi__err("bad comp method", "Corrupt PNG"); ; 4633 : filter = stbi__get8(s); if (filter) return stbi__err("bad filter method", "Corrupt PNG"); ; 4634 : interlace = stbi__get8(s); if (interlace > 1) return stbi__err("bad interlace method", "Corrupt PNG"); ; 4635 : if (!s->img_x || !s->img_y) return stbi__err("0-pixel image", "Corrupt PNG"); ; 4636 : if (!pal_img_n) { ; 4637 : s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); ; 4638 : if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); ; 4639 : } ; 4640 : else { ; 4641 : // if paletted, then pal_n is our final components, and ; 4642 : // img_n is # components to decompress/filter. ; 4643 : s->img_n = 1; ; 4644 : if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large", "Corrupt PNG"); ; 4645 : } ; 4646 : // even with SCAN_header, have to scan to see if we have a tRNS ; 4647 : break; ; 4648 : } ; 4649 : ; 4650 : case STBI__PNG_TYPE('P', 'L', 'T', 'E'): { ; 4651 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4652 : if (c.length > 256 * 3) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4653 : pal_len = c.length / 3; ; 4654 : if (pal_len * 3 != c.length) return stbi__err("invalid PLTE", "Corrupt PNG"); ; 4655 : for (i = 0; i < pal_len; ++i) { ; 4656 : palette[i * 4 + 0] = stbi__get8(s); ; 4657 : palette[i * 4 + 1] = stbi__get8(s); ; 4658 : palette[i * 4 + 2] = stbi__get8(s); ; 4659 : palette[i * 4 + 3] = 255; ; 4660 : } ; 4661 : break; ; 4662 : } ; 4663 : ; 4664 : case STBI__PNG_TYPE('t', 'R', 'N', 'S'): { ; 4665 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4666 : if (z->idata) return stbi__err("tRNS after IDAT", "Corrupt PNG"); ; 4667 : if (pal_img_n) { ; 4668 : if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } ; 4669 : if (pal_len == 0) return stbi__err("tRNS before PLTE", "Corrupt PNG"); ; 4670 : if (c.length > pal_len) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4671 : pal_img_n = 4; ; 4672 : for (i = 0; i < c.length; ++i) ; 4673 : palette[i * 4 + 3] = stbi__get8(s); ; 4674 : } ; 4675 : else { ; 4676 : if (!(s->img_n & 1)) return stbi__err("tRNS with alpha", "Corrupt PNG"); ; 4677 : if (c.length != (stbi__uint32)s->img_n * 2) return stbi__err("bad tRNS len", "Corrupt PNG"); ; 4678 : has_trans = 1; ; 4679 : // non-paletted with tRNS = constant alpha. if header-scanning, we can stop now. ; 4680 : if (scan == STBI__SCAN_header) { ++s->img_n; return 1; } ; 4681 : if (z->depth == 16) { ; 4682 : for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is ; 4683 : } ; 4684 : else { ; 4685 : for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger ; 4686 : } ; 4687 : } ; 4688 : break; ; 4689 : } ; 4690 : ; 4691 : case STBI__PNG_TYPE('I', 'D', 'A', 'T'): { ; 4692 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4693 : if (pal_img_n && !pal_len) return stbi__err("no PLTE", "Corrupt PNG"); ; 4694 : if (scan == STBI__SCAN_header) { ; 4695 : // header scan definitely stops at first IDAT ; 4696 : if (pal_img_n) ; 4697 : s->img_n = pal_img_n; ; 4698 : return 1; ; 4699 : } ; 4700 : if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes"); ; 4701 : if ((int)(ioff + c.length) < (int)ioff) return 0; ; 4702 : if (ioff + c.length > idata_limit) { ; 4703 : stbi__uint32 idata_limit_old = idata_limit; ; 4704 : stbi_uc* p; ; 4705 : if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; ; 4706 : while (ioff + c.length > idata_limit) ; 4707 : idata_limit *= 2; ; 4708 : STBI_NOTUSED(idata_limit_old); ; 4709 : p = (stbi_uc*)STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); ; 4710 : z->idata = p; ; 4711 : } ; 4712 : if (!stbi__getn(s, z->idata + ioff, c.length)) return stbi__err("outofdata", "Corrupt PNG"); ; 4713 : ioff += c.length; ; 4714 : break; ; 4715 : } ; 4716 : ; 4717 : case STBI__PNG_TYPE('I', 'E', 'N', 'D'): { ; 4718 : stbi__uint32 raw_len, bpl; ; 4719 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4720 : if (scan != STBI__SCAN_load) return 1; ; 4721 : if (z->idata == NULL) return stbi__err("no IDAT", "Corrupt PNG"); ; 4722 : // initial guess for decoded data size to avoid unnecessary reallocs ; 4723 : bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component ; 4724 : raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; ; 4725 : z->expanded = (stbi_uc*)stbi_zlib_decode_malloc_guesssize_headerflag((char*)z->idata, ioff, raw_len, (int*)&raw_len, !is_iphone); ; 4726 : if (z->expanded == NULL) return 0; // zlib should set error ; 4727 : STBI_FREE(z->idata); z->idata = NULL; ; 4728 : if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) ; 4729 : s->img_out_n = s->img_n + 1; ; 4730 : else ; 4731 : s->img_out_n = s->img_n; ; 4732 : if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; ; 4733 : if (has_trans) { ; 4734 : if (z->depth == 16) { ; 4735 : if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; ; 4736 : } ; 4737 : else { ; 4738 : if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; ; 4739 : } ; 4740 : } ; 4741 : if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) ; 4742 : stbi__de_iphone(z); ; 4743 : if (pal_img_n) { ; 4744 : // pal_img_n == 3 or 4 ; 4745 : s->img_n = pal_img_n; // record the actual colors we had ; 4746 : s->img_out_n = pal_img_n; ; 4747 : if (req_comp >= 3) s->img_out_n = req_comp; ; 4748 : if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) ; 4749 : return 0; ; 4750 : } ; 4751 : else if (has_trans) { ; 4752 : // non-paletted image with tRNS -> source image has (constant) alpha ; 4753 : ++s->img_n; ; 4754 : } ; 4755 : STBI_FREE(z->expanded); z->expanded = NULL; ; 4756 : // end of PNG chunk, read and skip CRC ; 4757 : stbi__get32be(s); ; 4758 : return 1; ; 4759 : } ; 4760 : ; 4761 : default: ; 4762 : // if critical, fail ; 4763 : if (first) return stbi__err("first not IHDR", "Corrupt PNG"); ; 4764 : if ((c.type & (1 << 29)) == 0) { ; 4765 : #ifndef STBI_NO_FAILURE_STRINGS ; 4766 : // not threadsafe ; 4767 : static char invalid_chunk[] = "XXXX PNG chunk not known"; ; 4768 : invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); ; 4769 : invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); ; 4770 : invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); ; 4771 : invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); ; 4772 : #endif ; 4773 : return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); ; 4774 : } ; 4775 : stbi__skip(s, c.length); ; 4776 : break; ; 4777 : } ; 4778 : // end of PNG chunk, read and skip CRC ; 4779 : stbi__get32be(s); ; 4780 : } ; 4781 : } ; 4782 : ; 4783 : static void* stbi__do_png(stbi__png* p, int* x, int* y, int* n, int req_comp, stbi__result_info* ri) ; 4784 : { ; 4785 : void* result = NULL; ; 4786 : if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); ; 4787 : if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { ; 4788 : if (p->depth <= 8) ; 4789 : ri->bits_per_channel = 8; ; 4790 : else if (p->depth == 16) ; 4791 : ri->bits_per_channel = 16; ; 4792 : else ; 4793 : return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth"); ; 4794 : result = p->out; ; 4795 : p->out = NULL; ; 4796 : if (req_comp && req_comp != p->s->img_out_n) { ; 4797 : if (ri->bits_per_channel == 8) ; 4798 : result = stbi__convert_format((unsigned char*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4799 : else ; 4800 : result = stbi__convert_format16((stbi__uint16*)result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); ; 4801 : p->s->img_out_n = req_comp; ; 4802 : if (result == NULL) return result; ; 4803 : } ; 4804 : *x = p->s->img_x; ; 4805 : *y = p->s->img_y; ; 4806 : if (n) *n = p->s->img_n; ; 4807 : } ; 4808 : STBI_FREE(p->out); p->out = NULL; ; 4809 : STBI_FREE(p->expanded); p->expanded = NULL; ; 4810 : STBI_FREE(p->idata); p->idata = NULL; ; 4811 : ; 4812 : return result; ; 4813 : } ; 4814 : ; 4815 : static void* stbi__png_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 4816 : { ; 4817 : stbi__png p; ; 4818 : p.s = s; ; 4819 : return stbi__do_png(&p, x, y, comp, req_comp, ri); ; 4820 : } ; 4821 : ; 4822 : static int stbi__png_test(stbi__context* s) ; 4823 : { ; 4824 : int r; ; 4825 : r = stbi__check_png_header(s); ; 4826 : stbi__rewind(s); ; 4827 : return r; ; 4828 : } ; 4829 : ; 4830 : static int stbi__png_info_raw(stbi__png* p, int* x, int* y, int* comp) ; 4831 : { ; 4832 : if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { ; 4833 : stbi__rewind(p->s); ; 4834 : return 0; ; 4835 : } ; 4836 : if (x) *x = p->s->img_x; ; 4837 : if (y) *y = p->s->img_y; ; 4838 : if (comp) *comp = p->s->img_n; ; 4839 : return 1; ; 4840 : } ; 4841 : ; 4842 : static int stbi__png_info(stbi__context* s, int* x, int* y, int* comp) ; 4843 : { ; 4844 : stbi__png p; ; 4845 : p.s = s; ; 4846 : return stbi__png_info_raw(&p, x, y, comp); ; 4847 : } ; 4848 : ; 4849 : static int stbi__png_is16(stbi__context* s) ; 4850 : { ; 4851 : stbi__png p; ; 4852 : p.s = s; ; 4853 : if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) ; 4854 : return 0; ; 4855 : if (p.depth != 16) { ; 4856 : stbi__rewind(p.s); ; 4857 : return 0; ; 4858 : } ; 4859 : return 1; ; 4860 : } ; 4861 : #endif ; 4862 : ; 4863 : // Microsoft/Windows BMP image ; 4864 : ; 4865 : #ifndef STBI_NO_BMP ; 4866 : static int stbi__bmp_test_raw(stbi__context* s) ; 4867 : { ; 4868 : int r; ; 4869 : int sz; ; 4870 : if (stbi__get8(s) != 'B') return 0; ; 4871 : if (stbi__get8(s) != 'M') return 0; ; 4872 : stbi__get32le(s); // discard filesize ; 4873 : stbi__get16le(s); // discard reserved ; 4874 : stbi__get16le(s); // discard reserved ; 4875 : stbi__get32le(s); // discard data offset ; 4876 : sz = stbi__get32le(s); ; 4877 : r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); ; 4878 : return r; ; 4879 : } ; 4880 : ; 4881 : static int stbi__bmp_test(stbi__context* s) ; 4882 : { ; 4883 : int r = stbi__bmp_test_raw(s); ; 4884 : stbi__rewind(s); ; 4885 : return r; ; 4886 : } ; 4887 : ; 4888 : // returns 0..31 for the highest set bit ; 4889 : static int stbi__high_bit(unsigned int z) ; 4890 : { ; 4891 : int n = 0; ; 4892 : if (z == 0) return -1; ; 4893 : if (z >= 0x10000) { n += 16; z >>= 16; } ; 4894 : if (z >= 0x00100) { n += 8; z >>= 8; } ; 4895 : if (z >= 0x00010) { n += 4; z >>= 4; } ; 4896 : if (z >= 0x00004) { n += 2; z >>= 2; } ; 4897 : if (z >= 0x00002) { n += 1;/* >>= 1;*/ } ; 4898 : return n; ; 4899 : } ; 4900 : ; 4901 : static int stbi__bitcount(unsigned int a) ; 4902 : { ; 4903 : a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 ; 4904 : a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 ; 4905 : a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits ; 4906 : a = (a + (a >> 8)); // max 16 per 8 bits ; 4907 : a = (a + (a >> 16)); // max 32 per 8 bits ; 4908 : return a & 0xff; ; 4909 : } ; 4910 : ; 4911 : // extract an arbitrarily-aligned N-bit value (N=bits) ; 4912 : // from v, and then make it 8-bits long and fractionally ; 4913 : // extend it to full full range. ; 4914 : static int stbi__shiftsigned(unsigned int v, int shift, int bits) ; 4915 : { ; 4916 : static unsigned int mul_table[9] = { ; 4917 : 0, ; 4918 : 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, ; 4919 : 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, ; 4920 : }; ; 4921 : static unsigned int shift_table[9] = { ; 4922 : 0, 0,0,1,0,2,4,6,0, ; 4923 : }; ; 4924 : if (shift < 0) ; 4925 : v <<= -shift; ; 4926 : else ; 4927 : v >>= shift; ; 4928 : STBI_ASSERT(v < 256); ; 4929 : v >>= (8 - bits); ; 4930 : STBI_ASSERT(bits >= 0 && bits <= 8); ; 4931 : return (int)((unsigned)v * mul_table[bits]) >> shift_table[bits]; ; 4932 : } ; 4933 : ; 4934 : typedef struct ; 4935 : { ; 4936 : int bpp, offset, hsz; ; 4937 : unsigned int mr, mg, mb, ma, all_a; ; 4938 : int extra_read; ; 4939 : } stbi__bmp_data; ; 4940 : ; 4941 : static int stbi__bmp_set_mask_defaults(stbi__bmp_data* info, int compress) ; 4942 : { ; 4943 : // BI_BITFIELDS specifies masks explicitly, don't override ; 4944 : if (compress == 3) ; 4945 : return 1; ; 4946 : ; 4947 : if (compress == 0) { ; 4948 : if (info->bpp == 16) { ; 4949 : info->mr = 31u << 10; ; 4950 : info->mg = 31u << 5; ; 4951 : info->mb = 31u << 0; ; 4952 : } ; 4953 : else if (info->bpp == 32) { ; 4954 : info->mr = 0xffu << 16; ; 4955 : info->mg = 0xffu << 8; ; 4956 : info->mb = 0xffu << 0; ; 4957 : info->ma = 0xffu << 24; ; 4958 : info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 ; 4959 : } ; 4960 : else { ; 4961 : // otherwise, use defaults, which is all-0 ; 4962 : info->mr = info->mg = info->mb = info->ma = 0; ; 4963 : } ; 4964 : return 1; ; 4965 : } ; 4966 : return 0; // error ; 4967 : } ; 4968 : ; 4969 : static void* stbi__bmp_parse_header(stbi__context* s, stbi__bmp_data* info) ; 4970 : { ; 4971 : int hsz; ; 4972 : if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); ; 4973 : stbi__get32le(s); // discard filesize ; 4974 : stbi__get16le(s); // discard reserved ; 4975 : stbi__get16le(s); // discard reserved ; 4976 : info->offset = stbi__get32le(s); ; 4977 : info->hsz = hsz = stbi__get32le(s); ; 4978 : info->mr = info->mg = info->mb = info->ma = 0; ; 4979 : info->extra_read = 14; ; 4980 : ; 4981 : if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP"); ; 4982 : ; 4983 : if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); ; 4984 : if (hsz == 12) { ; 4985 : s->img_x = stbi__get16le(s); ; 4986 : s->img_y = stbi__get16le(s); ; 4987 : } ; 4988 : else { ; 4989 : s->img_x = stbi__get32le(s); ; 4990 : s->img_y = stbi__get32le(s); ; 4991 : } ; 4992 : if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); ; 4993 : info->bpp = stbi__get16le(s); ; 4994 : if (hsz != 12) { ; 4995 : int compress = stbi__get32le(s); ; 4996 : if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); ; 4997 : if (compress >= 4) return stbi__errpuc("BMP JPEG/PNG", "BMP type not supported: unsupported compression"); // this includes PNG/JPEG modes ; 4998 : if (compress == 3 && info->bpp != 16 && info->bpp != 32) return stbi__errpuc("bad BMP", "bad BMP"); // bitfields requires 16 or 32 bits/pixel ; 4999 : stbi__get32le(s); // discard sizeof ; 5000 : stbi__get32le(s); // discard hres ; 5001 : stbi__get32le(s); // discard vres ; 5002 : stbi__get32le(s); // discard colorsused ; 5003 : stbi__get32le(s); // discard max important ; 5004 : if (hsz == 40 || hsz == 56) { ; 5005 : if (hsz == 56) { ; 5006 : stbi__get32le(s); ; 5007 : stbi__get32le(s); ; 5008 : stbi__get32le(s); ; 5009 : stbi__get32le(s); ; 5010 : } ; 5011 : if (info->bpp == 16 || info->bpp == 32) { ; 5012 : if (compress == 0) { ; 5013 : stbi__bmp_set_mask_defaults(info, compress); ; 5014 : } ; 5015 : else if (compress == 3) { ; 5016 : info->mr = stbi__get32le(s); ; 5017 : info->mg = stbi__get32le(s); ; 5018 : info->mb = stbi__get32le(s); ; 5019 : info->extra_read += 12; ; 5020 : // not documented, but generated by photoshop and handled by mspaint ; 5021 : if (info->mr == info->mg && info->mg == info->mb) { ; 5022 : // ?!?!? ; 5023 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5024 : } ; 5025 : } ; 5026 : else ; 5027 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5028 : } ; 5029 : } ; 5030 : else { ; 5031 : // V4/V5 header ; 5032 : int i; ; 5033 : if (hsz != 108 && hsz != 124) ; 5034 : return stbi__errpuc("bad BMP", "bad BMP"); ; 5035 : info->mr = stbi__get32le(s); ; 5036 : info->mg = stbi__get32le(s); ; 5037 : info->mb = stbi__get32le(s); ; 5038 : info->ma = stbi__get32le(s); ; 5039 : if (compress != 3) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs ; 5040 : stbi__bmp_set_mask_defaults(info, compress); ; 5041 : stbi__get32le(s); // discard color space ; 5042 : for (i = 0; i < 12; ++i) ; 5043 : stbi__get32le(s); // discard color space parameters ; 5044 : if (hsz == 124) { ; 5045 : stbi__get32le(s); // discard rendering intent ; 5046 : stbi__get32le(s); // discard offset of profile data ; 5047 : stbi__get32le(s); // discard size of profile data ; 5048 : stbi__get32le(s); // discard reserved ; 5049 : } ; 5050 : } ; 5051 : } ; 5052 : return (void*)1; ; 5053 : } ; 5054 : ; 5055 : static void* stbi__bmp_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5056 : { ; 5057 : stbi_uc* out; ; 5058 : unsigned int mr = 0, mg = 0, mb = 0, ma = 0, all_a; ; 5059 : stbi_uc pal[256][4]; ; 5060 : int psize = 0, i, j, width; ; 5061 : int flip_vertically, pad, target; ; 5062 : stbi__bmp_data info; ; 5063 : STBI_NOTUSED(ri); ; 5064 : ; 5065 : info.all_a = 255; ; 5066 : if (stbi__bmp_parse_header(s, &info) == NULL) ; 5067 : return NULL; // error code already set ; 5068 : ; 5069 : flip_vertically = ((int)s->img_y) > 0; ; 5070 : s->img_y = abs((int)s->img_y); ; 5071 : ; 5072 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5073 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5074 : ; 5075 : mr = info.mr; ; 5076 : mg = info.mg; ; 5077 : mb = info.mb; ; 5078 : ma = info.ma; ; 5079 : all_a = info.all_a; ; 5080 : ; 5081 : if (info.hsz == 12) { ; 5082 : if (info.bpp < 24) ; 5083 : psize = (info.offset - info.extra_read - 24) / 3; ; 5084 : } ; 5085 : else { ; 5086 : if (info.bpp < 16) ; 5087 : psize = (info.offset - info.extra_read - info.hsz) >> 2; ; 5088 : } ; 5089 : if (psize == 0) { ; 5090 : // accept some number of extra bytes after the header, but if the offset points either to before ; 5091 : // the header ends or implies a large amount of extra data, reject the file as malformed ; 5092 : int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); ; 5093 : int header_limit = 1024; // max we actually read is below 256 bytes currently. ; 5094 : int extra_data_limit = 256 * 4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. ; 5095 : if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { ; 5096 : return stbi__errpuc("bad header", "Corrupt BMP"); ; 5097 : } ; 5098 : // we established that bytes_read_so_far is positive and sensible. ; 5099 : // the first half of this test rejects offsets that are either too small positives, or ; 5100 : // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn ; 5101 : // ensures the number computed in the second half of the test can't overflow. ; 5102 : if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { ; 5103 : return stbi__errpuc("bad offset", "Corrupt BMP"); ; 5104 : } ; 5105 : else { ; 5106 : stbi__skip(s, info.offset - bytes_read_so_far); ; 5107 : } ; 5108 : } ; 5109 : ; 5110 : if (info.bpp == 24 && ma == 0xff000000) ; 5111 : s->img_n = 3; ; 5112 : else ; 5113 : s->img_n = ma ? 4 : 3; ; 5114 : if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 ; 5115 : target = req_comp; ; 5116 : else ; 5117 : target = s->img_n; // if they want monochrome, we'll post-convert ; 5118 : ; 5119 : // sanity-check size ; 5120 : if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) ; 5121 : return stbi__errpuc("too large", "Corrupt BMP"); ; 5122 : ; 5123 : out = (stbi_uc*)stbi__malloc_mad3(target, s->img_x, s->img_y, 0); ; 5124 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5125 : if (info.bpp < 16) { ; 5126 : int z = 0; ; 5127 : if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } ; 5128 : for (i = 0; i < psize; ++i) { ; 5129 : pal[i][2] = stbi__get8(s); ; 5130 : pal[i][1] = stbi__get8(s); ; 5131 : pal[i][0] = stbi__get8(s); ; 5132 : if (info.hsz != 12) stbi__get8(s); ; 5133 : pal[i][3] = 255; ; 5134 : } ; 5135 : stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); ; 5136 : if (info.bpp == 1) width = (s->img_x + 7) >> 3; ; 5137 : else if (info.bpp == 4) width = (s->img_x + 1) >> 1; ; 5138 : else if (info.bpp == 8) width = s->img_x; ; 5139 : else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } ; 5140 : pad = (-width) & 3; ; 5141 : if (info.bpp == 1) { ; 5142 : for (j = 0; j < (int)s->img_y; ++j) { ; 5143 : int bit_offset = 7, v = stbi__get8(s); ; 5144 : for (i = 0; i < (int)s->img_x; ++i) { ; 5145 : int color = (v >> bit_offset) & 0x1; ; 5146 : out[z++] = pal[color][0]; ; 5147 : out[z++] = pal[color][1]; ; 5148 : out[z++] = pal[color][2]; ; 5149 : if (target == 4) out[z++] = 255; ; 5150 : if (i + 1 == (int)s->img_x) break; ; 5151 : if ((--bit_offset) < 0) { ; 5152 : bit_offset = 7; ; 5153 : v = stbi__get8(s); ; 5154 : } ; 5155 : } ; 5156 : stbi__skip(s, pad); ; 5157 : } ; 5158 : } ; 5159 : else { ; 5160 : for (j = 0; j < (int)s->img_y; ++j) { ; 5161 : for (i = 0; i < (int)s->img_x; i += 2) { ; 5162 : int v = stbi__get8(s), v2 = 0; ; 5163 : if (info.bpp == 4) { ; 5164 : v2 = v & 15; ; 5165 : v >>= 4; ; 5166 : } ; 5167 : out[z++] = pal[v][0]; ; 5168 : out[z++] = pal[v][1]; ; 5169 : out[z++] = pal[v][2]; ; 5170 : if (target == 4) out[z++] = 255; ; 5171 : if (i + 1 == (int)s->img_x) break; ; 5172 : v = (info.bpp == 8) ? stbi__get8(s) : v2; ; 5173 : out[z++] = pal[v][0]; ; 5174 : out[z++] = pal[v][1]; ; 5175 : out[z++] = pal[v][2]; ; 5176 : if (target == 4) out[z++] = 255; ; 5177 : } ; 5178 : stbi__skip(s, pad); ; 5179 : } ; 5180 : } ; 5181 : } ; 5182 : else { ; 5183 : int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; ; 5184 : int z = 0; ; 5185 : int easy = 0; ; 5186 : stbi__skip(s, info.offset - info.extra_read - info.hsz); ; 5187 : if (info.bpp == 24) width = 3 * s->img_x; ; 5188 : else if (info.bpp == 16) width = 2 * s->img_x; ; 5189 : else /* bpp = 32 and pad = 0 */ width = 0; ; 5190 : pad = (-width) & 3; ; 5191 : if (info.bpp == 24) { ; 5192 : easy = 1; ; 5193 : } ; 5194 : else if (info.bpp == 32) { ; 5195 : if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) ; 5196 : easy = 2; ; 5197 : } ; 5198 : if (!easy) { ; 5199 : if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5200 : // right shift amt to put high bit in position #7 ; 5201 : rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); ; 5202 : gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); ; 5203 : bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ; 5204 : ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); ; 5205 : if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } ; 5206 : } ; 5207 : for (j = 0; j < (int)s->img_y; ++j) { ; 5208 : if (easy) { ; 5209 : for (i = 0; i < (int)s->img_x; ++i) { ; 5210 : unsigned char a; ; 5211 : out[z + 2] = stbi__get8(s); ; 5212 : out[z + 1] = stbi__get8(s); ; 5213 : out[z + 0] = stbi__get8(s); ; 5214 : z += 3; ; 5215 : a = (easy == 2 ? stbi__get8(s) : 255); ; 5216 : all_a |= a; ; 5217 : if (target == 4) out[z++] = a; ; 5218 : } ; 5219 : } ; 5220 : else { ; 5221 : int bpp = info.bpp; ; 5222 : for (i = 0; i < (int)s->img_x; ++i) { ; 5223 : stbi__uint32 v = (bpp == 16 ? (stbi__uint32)stbi__get16le(s) : stbi__get32le(s)); ; 5224 : unsigned int a; ; 5225 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); ; 5226 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); ; 5227 : out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); ; 5228 : a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); ; 5229 : all_a |= a; ; 5230 : if (target == 4) out[z++] = STBI__BYTECAST(a); ; 5231 : } ; 5232 : } ; 5233 : stbi__skip(s, pad); ; 5234 : } ; 5235 : } ; 5236 : ; 5237 : // if alpha channel is all 0s, replace with all 255s ; 5238 : if (target == 4 && all_a == 0) ; 5239 : for (i = 4 * s->img_x * s->img_y - 1; i >= 0; i -= 4) ; 5240 : out[i] = 255; ; 5241 : ; 5242 : if (flip_vertically) { ; 5243 : stbi_uc t; ; 5244 : for (j = 0; j < (int)s->img_y >> 1; ++j) { ; 5245 : stbi_uc* p1 = out + j * s->img_x * target; ; 5246 : stbi_uc* p2 = out + (s->img_y - 1 - j) * s->img_x * target; ; 5247 : for (i = 0; i < (int)s->img_x * target; ++i) { ; 5248 : t = p1[i]; p1[i] = p2[i]; p2[i] = t; ; 5249 : } ; 5250 : } ; 5251 : } ; 5252 : ; 5253 : if (req_comp && req_comp != target) { ; 5254 : out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); ; 5255 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5256 : } ; 5257 : ; 5258 : *x = s->img_x; ; 5259 : *y = s->img_y; ; 5260 : if (comp) *comp = s->img_n; ; 5261 : return out; ; 5262 : } ; 5263 : #endif ; 5264 : ; 5265 : // Targa Truevision - TGA ; 5266 : // by Jonathan Dummer ; 5267 : #ifndef STBI_NO_TGA ; 5268 : // returns STBI_rgb or whatever, 0 on error ; 5269 : static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) ; 5270 : { ; 5271 : // only RGB or RGBA (incl. 16bit) or grey allowed ; 5272 : if (is_rgb16) *is_rgb16 = 0; ; 5273 : switch (bits_per_pixel) { ; 5274 : case 8: return STBI_grey; ; 5275 : case 16: if (is_grey) return STBI_grey_alpha; ; 5276 : // fallthrough ; 5277 : case 15: if (is_rgb16) *is_rgb16 = 1; ; 5278 : return STBI_rgb; ; 5279 : case 24: // fallthrough ; 5280 : case 32: return bits_per_pixel / 8; ; 5281 : default: return 0; ; 5282 : } ; 5283 : } ; 5284 : ; 5285 : static int stbi__tga_info(stbi__context* s, int* x, int* y, int* comp) ; 5286 : { ; 5287 : int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; ; 5288 : int sz, tga_colormap_type; ; 5289 : stbi__get8(s); // discard Offset ; 5290 : tga_colormap_type = stbi__get8(s); // colormap type ; 5291 : if (tga_colormap_type > 1) { ; 5292 : stbi__rewind(s); ; 5293 : return 0; // only RGB or indexed allowed ; 5294 : } ; 5295 : tga_image_type = stbi__get8(s); // image type ; 5296 : if (tga_colormap_type == 1) { // colormapped (paletted) image ; 5297 : if (tga_image_type != 1 && tga_image_type != 9) { ; 5298 : stbi__rewind(s); ; 5299 : return 0; ; 5300 : } ; 5301 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5302 : sz = stbi__get8(s); // check bits per palette color entry ; 5303 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) { ; 5304 : stbi__rewind(s); ; 5305 : return 0; ; 5306 : } ; 5307 : stbi__skip(s, 4); // skip image x and y origin ; 5308 : tga_colormap_bpp = sz; ; 5309 : } ; 5310 : else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE ; 5311 : if ((tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11)) { ; 5312 : stbi__rewind(s); ; 5313 : return 0; // only RGB or grey allowed, +/- RLE ; 5314 : } ; 5315 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5316 : tga_colormap_bpp = 0; ; 5317 : } ; 5318 : tga_w = stbi__get16le(s); ; 5319 : if (tga_w < 1) { ; 5320 : stbi__rewind(s); ; 5321 : return 0; // test width ; 5322 : } ; 5323 : tga_h = stbi__get16le(s); ; 5324 : if (tga_h < 1) { ; 5325 : stbi__rewind(s); ; 5326 : return 0; // test height ; 5327 : } ; 5328 : tga_bits_per_pixel = stbi__get8(s); // bits per pixel ; 5329 : stbi__get8(s); // ignore alpha bits ; 5330 : if (tga_colormap_bpp != 0) { ; 5331 : if ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { ; 5332 : // when using a colormap, tga_bits_per_pixel is the size of the indexes ; 5333 : // I don't think anything but 8 or 16bit indexes makes sense ; 5334 : stbi__rewind(s); ; 5335 : return 0; ; 5336 : } ; 5337 : tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); ; 5338 : } ; 5339 : else { ; 5340 : tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); ; 5341 : } ; 5342 : if (!tga_comp) { ; 5343 : stbi__rewind(s); ; 5344 : return 0; ; 5345 : } ; 5346 : if (x) *x = tga_w; ; 5347 : if (y) *y = tga_h; ; 5348 : if (comp) *comp = tga_comp; ; 5349 : return 1; // seems to have passed everything ; 5350 : } ; 5351 : ; 5352 : static int stbi__tga_test(stbi__context* s) ; 5353 : { ; 5354 : int res = 0; ; 5355 : int sz, tga_color_type; ; 5356 : stbi__get8(s); // discard Offset ; 5357 : tga_color_type = stbi__get8(s); // color type ; 5358 : if (tga_color_type > 1) goto errorEnd; // only RGB or indexed allowed ; 5359 : sz = stbi__get8(s); // image type ; 5360 : if (tga_color_type == 1) { // colormapped (paletted) image ; 5361 : if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 ; 5362 : stbi__skip(s, 4); // skip index of first colormap entry and number of entries ; 5363 : sz = stbi__get8(s); // check bits per palette color entry ; 5364 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5365 : stbi__skip(s, 4); // skip image x and y origin ; 5366 : } ; 5367 : else { // "normal" image w/o colormap ; 5368 : if ((sz != 2) && (sz != 3) && (sz != 10) && (sz != 11)) goto errorEnd; // only RGB or grey allowed, +/- RLE ; 5369 : stbi__skip(s, 9); // skip colormap specification and image x/y origin ; 5370 : } ; 5371 : if (stbi__get16le(s) < 1) goto errorEnd; // test width ; 5372 : if (stbi__get16le(s) < 1) goto errorEnd; // test height ; 5373 : sz = stbi__get8(s); // bits per pixel ; 5374 : if ((tga_color_type == 1) && (sz != 8) && (sz != 16)) goto errorEnd; // for colormapped images, bpp is size of an index ; 5375 : if ((sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32)) goto errorEnd; ; 5376 : ; 5377 : res = 1; // if we got this far, everything's good and we can return 1 instead of 0 ; 5378 : ; 5379 : errorEnd: ; 5380 : stbi__rewind(s); ; 5381 : return res; ; 5382 : } ; 5383 : ; 5384 : // read 16bit value and convert to 24bit RGB ; 5385 : static void stbi__tga_read_rgb16(stbi__context* s, stbi_uc* out) ; 5386 : { ; 5387 : stbi__uint16 px = (stbi__uint16)stbi__get16le(s); ; 5388 : stbi__uint16 fiveBitMask = 31; ; 5389 : // we have 3 channels with 5bits each ; 5390 : int r = (px >> 10) & fiveBitMask; ; 5391 : int g = (px >> 5) & fiveBitMask; ; 5392 : int b = px & fiveBitMask; ; 5393 : // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later ; 5394 : out[0] = (stbi_uc)((r * 255) / 31); ; 5395 : out[1] = (stbi_uc)((g * 255) / 31); ; 5396 : out[2] = (stbi_uc)((b * 255) / 31); ; 5397 : ; 5398 : // some people claim that the most significant bit might be used for alpha ; 5399 : // (possibly if an alpha-bit is set in the "image descriptor byte") ; 5400 : // but that only made 16bit test images completely translucent.. ; 5401 : // so let's treat all 15 and 16bit TGAs as RGB with no alpha. ; 5402 : } ; 5403 : ; 5404 : static void* stbi__tga_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 5405 : { ; 5406 : // read in the TGA header stuff ; 5407 : int tga_offset = stbi__get8(s); ; 5408 : int tga_indexed = stbi__get8(s); ; 5409 : int tga_image_type = stbi__get8(s); ; 5410 : int tga_is_RLE = 0; ; 5411 : int tga_palette_start = stbi__get16le(s); ; 5412 : int tga_palette_len = stbi__get16le(s); ; 5413 : int tga_palette_bits = stbi__get8(s); ; 5414 : int tga_x_origin = stbi__get16le(s); ; 5415 : int tga_y_origin = stbi__get16le(s); ; 5416 : int tga_width = stbi__get16le(s); ; 5417 : int tga_height = stbi__get16le(s); ; 5418 : int tga_bits_per_pixel = stbi__get8(s); ; 5419 : int tga_comp, tga_rgb16 = 0; ; 5420 : int tga_inverted = stbi__get8(s); ; 5421 : // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) ; 5422 : // image data ; 5423 : unsigned char* tga_data; ; 5424 : unsigned char* tga_palette = NULL; ; 5425 : int i, j; ; 5426 : unsigned char raw_data[4] = { 0 }; ; 5427 : int RLE_count = 0; ; 5428 : int RLE_repeating = 0; ; 5429 : int read_next_pixel = 1; ; 5430 : STBI_NOTUSED(ri); ; 5431 : STBI_NOTUSED(tga_x_origin); // @TODO ; 5432 : STBI_NOTUSED(tga_y_origin); // @TODO ; 5433 : ; 5434 : if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5435 : if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5436 : ; 5437 : // do a tiny bit of precessing ; 5438 : if (tga_image_type >= 8) ; 5439 : { ; 5440 : tga_image_type -= 8; ; 5441 : tga_is_RLE = 1; ; 5442 : } ; 5443 : tga_inverted = 1 - ((tga_inverted >> 5) & 1); ; 5444 : ; 5445 : // If I'm paletted, then I'll use the number of bits from the palette ; 5446 : if (tga_indexed) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); ; 5447 : else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); ; 5448 : ; 5449 : if (!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency ; 5450 : return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); ; 5451 : ; 5452 : // tga info ; 5453 : *x = tga_width; ; 5454 : *y = tga_height; ; 5455 : if (comp) *comp = tga_comp; ; 5456 : ; 5457 : if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) ; 5458 : return stbi__errpuc("too large", "Corrupt TGA"); ; 5459 : ; 5460 : tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); ; 5461 : if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); ; 5462 : ; 5463 : // skip to the data's starting position (offset usually = 0) ; 5464 : stbi__skip(s, tga_offset); ; 5465 : ; 5466 : if (!tga_indexed && !tga_is_RLE && !tga_rgb16) { ; 5467 : for (i = 0; i < tga_height; ++i) { ; 5468 : int row = tga_inverted ? tga_height - i - 1 : i; ; 5469 : stbi_uc* tga_row = tga_data + row * tga_width * tga_comp; ; 5470 : stbi__getn(s, tga_row, tga_width * tga_comp); ; 5471 : } ; 5472 : } ; 5473 : else { ; 5474 : // do I need to load a palette? ; 5475 : if (tga_indexed) ; 5476 : { ; 5477 : if (tga_palette_len == 0) { /* you have to have at least one entry! */ ; 5478 : STBI_FREE(tga_data); ; 5479 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5480 : } ; 5481 : ; 5482 : // any data to skip? (offset usually = 0) ; 5483 : stbi__skip(s, tga_palette_start); ; 5484 : // load the palette ; 5485 : tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); ; 5486 : if (!tga_palette) { ; 5487 : STBI_FREE(tga_data); ; 5488 : return stbi__errpuc("outofmem", "Out of memory"); ; 5489 : } ; 5490 : if (tga_rgb16) { ; 5491 : stbi_uc* pal_entry = tga_palette; ; 5492 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5493 : for (i = 0; i < tga_palette_len; ++i) { ; 5494 : stbi__tga_read_rgb16(s, pal_entry); ; 5495 : pal_entry += tga_comp; ; 5496 : } ; 5497 : } ; 5498 : else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { ; 5499 : STBI_FREE(tga_data); ; 5500 : STBI_FREE(tga_palette); ; 5501 : return stbi__errpuc("bad palette", "Corrupt TGA"); ; 5502 : } ; 5503 : } ; 5504 : // load the data ; 5505 : for (i = 0; i < tga_width * tga_height; ++i) ; 5506 : { ; 5507 : // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? ; 5508 : if (tga_is_RLE) ; 5509 : { ; 5510 : if (RLE_count == 0) ; 5511 : { ; 5512 : // yep, get the next byte as a RLE command ; 5513 : int RLE_cmd = stbi__get8(s); ; 5514 : RLE_count = 1 + (RLE_cmd & 127); ; 5515 : RLE_repeating = RLE_cmd >> 7; ; 5516 : read_next_pixel = 1; ; 5517 : } ; 5518 : else if (!RLE_repeating) ; 5519 : { ; 5520 : read_next_pixel = 1; ; 5521 : } ; 5522 : } ; 5523 : else ; 5524 : { ; 5525 : read_next_pixel = 1; ; 5526 : } ; 5527 : // OK, if I need to read a pixel, do it now ; 5528 : if (read_next_pixel) ; 5529 : { ; 5530 : // load however much data we did have ; 5531 : if (tga_indexed) ; 5532 : { ; 5533 : // read in index, then perform the lookup ; 5534 : int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); ; 5535 : if (pal_idx >= tga_palette_len) { ; 5536 : // invalid index ; 5537 : pal_idx = 0; ; 5538 : } ; 5539 : pal_idx *= tga_comp; ; 5540 : for (j = 0; j < tga_comp; ++j) { ; 5541 : raw_data[j] = tga_palette[pal_idx + j]; ; 5542 : } ; 5543 : } ; 5544 : else if (tga_rgb16) { ; 5545 : STBI_ASSERT(tga_comp == STBI_rgb); ; 5546 : stbi__tga_read_rgb16(s, raw_data); ; 5547 : } ; 5548 : else { ; 5549 : // read in the data raw ; 5550 : for (j = 0; j < tga_comp; ++j) { ; 5551 : raw_data[j] = stbi__get8(s); ; 5552 : } ; 5553 : } ; 5554 : // clear the reading flag for the next pixel ; 5555 : read_next_pixel = 0; ; 5556 : } // end of reading a pixel ; 5557 : ; 5558 : // copy data ; 5559 : for (j = 0; j < tga_comp; ++j) ; 5560 : tga_data[i * tga_comp + j] = raw_data[j]; ; 5561 : ; 5562 : // in case we're in RLE mode, keep counting down ; 5563 : --RLE_count; ; 5564 : } ; 5565 : // do I need to invert the image? ; 5566 : if (tga_inverted) ; 5567 : { ; 5568 : for (j = 0; j * 2 < tga_height; ++j) ; 5569 : { ; 5570 : int index1 = j * tga_width * tga_comp; ; 5571 : int index2 = (tga_height - 1 - j) * tga_width * tga_comp; ; 5572 : for (i = tga_width * tga_comp; i > 0; --i) ; 5573 : { ; 5574 : unsigned char temp = tga_data[index1]; ; 5575 : tga_data[index1] = tga_data[index2]; ; 5576 : tga_data[index2] = temp; ; 5577 : ++index1; ; 5578 : ++index2; ; 5579 : } ; 5580 : } ; 5581 : } ; 5582 : // clear my palette, if I had one ; 5583 : if (tga_palette != NULL) ; 5584 : { ; 5585 : STBI_FREE(tga_palette); ; 5586 : } ; 5587 : } ; 5588 : ; 5589 : // swap RGB - if the source data was RGB16, it already is in the right order ; 5590 : if (tga_comp >= 3 && !tga_rgb16) ; 5591 : { ; 5592 : unsigned char* tga_pixel = tga_data; ; 5593 : for (i = 0; i < tga_width * tga_height; ++i) ; 5594 : { ; 5595 : unsigned char temp = tga_pixel[0]; ; 5596 : tga_pixel[0] = tga_pixel[2]; ; 5597 : tga_pixel[2] = temp; ; 5598 : tga_pixel += tga_comp; ; 5599 : } ; 5600 : } ; 5601 : ; 5602 : // convert to target component count ; 5603 : if (req_comp && req_comp != tga_comp) ; 5604 : tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); ; 5605 : ; 5606 : // the things I do to get rid of an error message, and yet keep ; 5607 : // Microsoft's C compilers happy... [8^( ; 5608 : tga_palette_start = tga_palette_len = tga_palette_bits = ; 5609 : tga_x_origin = tga_y_origin = 0; ; 5610 : STBI_NOTUSED(tga_palette_start); ; 5611 : // OK, done ; 5612 : return tga_data; ; 5613 : } ; 5614 : #endif ; 5615 : ; 5616 : // ************************************************************************************************* ; 5617 : // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB ; 5618 : ; 5619 : #ifndef STBI_NO_PSD ; 5620 : static int stbi__psd_test(stbi__context* s) ; 5621 : { ; 5622 : int r = (stbi__get32be(s) == 0x38425053); ; 5623 : stbi__rewind(s); ; 5624 : return r; ; 5625 : } ; 5626 : ; 5627 : static int stbi__psd_decode_rle(stbi__context* s, stbi_uc* p, int pixelCount) ; 5628 : { ; 5629 : int count, nleft, len; ; 5630 : ; 5631 : count = 0; ; 5632 : while ((nleft = pixelCount - count) > 0) { ; 5633 : len = stbi__get8(s); ; 5634 : if (len == 128) { ; 5635 : // No-op. ; 5636 : } ; 5637 : else if (len < 128) { ; 5638 : // Copy next len+1 bytes literally. ; 5639 : len++; ; 5640 : if (len > nleft) return 0; // corrupt data ; 5641 : count += len; ; 5642 : while (len) { ; 5643 : *p = stbi__get8(s); ; 5644 : p += 4; ; 5645 : len--; ; 5646 : } ; 5647 : } ; 5648 : else if (len > 128) { ; 5649 : stbi_uc val; ; 5650 : // Next -len+1 bytes in the dest are replicated from next source byte. ; 5651 : // (Interpret len as a negative 8-bit int.) ; 5652 : len = 257 - len; ; 5653 : if (len > nleft) return 0; // corrupt data ; 5654 : val = stbi__get8(s); ; 5655 : count += len; ; 5656 : while (len) { ; 5657 : *p = val; ; 5658 : p += 4; ; 5659 : len--; ; 5660 : } ; 5661 : } ; 5662 : } ; 5663 : ; 5664 : return 1; ; 5665 : } ; 5666 : ; 5667 : static void* stbi__psd_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri, int bpc) ; 5668 : { ; 5669 : int pixelCount; ; 5670 : int channelCount, compression; ; 5671 : int channel, i; ; 5672 : int bitdepth; ; 5673 : int w, h; ; 5674 : stbi_uc* out; ; 5675 : STBI_NOTUSED(ri); ; 5676 : ; 5677 : // Check identifier ; 5678 : if (stbi__get32be(s) != 0x38425053) // "8BPS" ; 5679 : return stbi__errpuc("not PSD", "Corrupt PSD image"); ; 5680 : ; 5681 : // Check file type version. ; 5682 : if (stbi__get16be(s) != 1) ; 5683 : return stbi__errpuc("wrong version", "Unsupported version of PSD image"); ; 5684 : ; 5685 : // Skip 6 reserved bytes. ; 5686 : stbi__skip(s, 6); ; 5687 : ; 5688 : // Read the number of channels (R, G, B, A, etc). ; 5689 : channelCount = stbi__get16be(s); ; 5690 : if (channelCount < 0 || channelCount > 16) ; 5691 : return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); ; 5692 : ; 5693 : // Read the rows and columns of the image. ; 5694 : h = stbi__get32be(s); ; 5695 : w = stbi__get32be(s); ; 5696 : ; 5697 : if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5698 : if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 5699 : ; 5700 : // Make sure the depth is 8 bits. ; 5701 : bitdepth = stbi__get16be(s); ; 5702 : if (bitdepth != 8 && bitdepth != 16) ; 5703 : return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); ; 5704 : ; 5705 : // Make sure the color mode is RGB. ; 5706 : // Valid options are: ; 5707 : // 0: Bitmap ; 5708 : // 1: Grayscale ; 5709 : // 2: Indexed color ; 5710 : // 3: RGB color ; 5711 : // 4: CMYK color ; 5712 : // 7: Multichannel ; 5713 : // 8: Duotone ; 5714 : // 9: Lab color ; 5715 : if (stbi__get16be(s) != 3) ; 5716 : return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); ; 5717 : ; 5718 : // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) ; 5719 : stbi__skip(s, stbi__get32be(s)); ; 5720 : ; 5721 : // Skip the image resources. (resolution, pen tool paths, etc) ; 5722 : stbi__skip(s, stbi__get32be(s)); ; 5723 : ; 5724 : // Skip the reserved data. ; 5725 : stbi__skip(s, stbi__get32be(s)); ; 5726 : ; 5727 : // Find out if the data is compressed. ; 5728 : // Known values: ; 5729 : // 0: no compression ; 5730 : // 1: RLE compressed ; 5731 : compression = stbi__get16be(s); ; 5732 : if (compression > 1) ; 5733 : return stbi__errpuc("bad compression", "PSD has an unknown compression format"); ; 5734 : ; 5735 : // Check size ; 5736 : if (!stbi__mad3sizes_valid(4, w, h, 0)) ; 5737 : return stbi__errpuc("too large", "Corrupt PSD"); ; 5738 : ; 5739 : // Create the destination image. ; 5740 : ; 5741 : if (!compression && bitdepth == 16 && bpc == 16) { ; 5742 : out = (stbi_uc*)stbi__malloc_mad3(8, w, h, 0); ; 5743 : ri->bits_per_channel = 16; ; 5744 : } ; 5745 : else ; 5746 : out = (stbi_uc*)stbi__malloc(4 * w * h); ; 5747 : ; 5748 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); ; 5749 : pixelCount = w * h; ; 5750 : ; 5751 : // Initialize the data to zero. ; 5752 : //memset( out, 0, pixelCount * 4 ); ; 5753 : ; 5754 : // Finally, the image data. ; 5755 : if (compression) { ; 5756 : // RLE as used by .PSD and .TIFF ; 5757 : // Loop until you get the number of unpacked bytes you are expecting: ; 5758 : // Read the next source byte into n. ; 5759 : // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. ; 5760 : // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. ; 5761 : // Else if n is 128, noop. ; 5762 : // Endloop ; 5763 : ; 5764 : // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, ; 5765 : // which we're going to just skip. ; 5766 : stbi__skip(s, h * channelCount * 2); ; 5767 : ; 5768 : // Read the RLE data by channel. ; 5769 : for (channel = 0; channel < 4; channel++) { ; 5770 : stbi_uc* p; ; 5771 : ; 5772 : p = out + channel; ; 5773 : if (channel >= channelCount) { ; 5774 : // Fill this channel with default data. ; 5775 : for (i = 0; i < pixelCount; i++, p += 4) ; 5776 : *p = (channel == 3 ? 255 : 0); ; 5777 : } ; 5778 : else { ; 5779 : // Read the RLE data. ; 5780 : if (!stbi__psd_decode_rle(s, p, pixelCount)) { ; 5781 : STBI_FREE(out); ; 5782 : return stbi__errpuc("corrupt", "bad RLE data"); ; 5783 : } ; 5784 : } ; 5785 : } ; 5786 : } ; 5787 : else { ; 5788 : // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) ; 5789 : // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. ; 5790 : ; 5791 : // Read the data by channel. ; 5792 : for (channel = 0; channel < 4; channel++) { ; 5793 : if (channel >= channelCount) { ; 5794 : // Fill this channel with default data. ; 5795 : if (bitdepth == 16 && bpc == 16) { ; 5796 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5797 : stbi__uint16 val = channel == 3 ? 65535 : 0; ; 5798 : for (i = 0; i < pixelCount; i++, q += 4) ; 5799 : *q = val; ; 5800 : } ; 5801 : else { ; 5802 : stbi_uc* p = out + channel; ; 5803 : stbi_uc val = channel == 3 ? 255 : 0; ; 5804 : for (i = 0; i < pixelCount; i++, p += 4) ; 5805 : *p = val; ; 5806 : } ; 5807 : } ; 5808 : else { ; 5809 : if (ri->bits_per_channel == 16) { // output bpc ; 5810 : stbi__uint16* q = ((stbi__uint16*)out) + channel; ; 5811 : for (i = 0; i < pixelCount; i++, q += 4) ; 5812 : *q = (stbi__uint16)stbi__get16be(s); ; 5813 : } ; 5814 : else { ; 5815 : stbi_uc* p = out + channel; ; 5816 : if (bitdepth == 16) { // input bpc ; 5817 : for (i = 0; i < pixelCount; i++, p += 4) ; 5818 : *p = (stbi_uc)(stbi__get16be(s) >> 8); ; 5819 : } ; 5820 : else { ; 5821 : for (i = 0; i < pixelCount; i++, p += 4) ; 5822 : *p = stbi__get8(s); ; 5823 : } ; 5824 : } ; 5825 : } ; 5826 : } ; 5827 : } ; 5828 : ; 5829 : // remove weird white matte from PSD ; 5830 : if (channelCount >= 4) { ; 5831 : if (ri->bits_per_channel == 16) { ; 5832 : for (i = 0; i < w * h; ++i) { ; 5833 : stbi__uint16* pixel = (stbi__uint16*)out + 4 * i; ; 5834 : if (pixel[3] != 0 && pixel[3] != 65535) { ; 5835 : float a = pixel[3] / 65535.0f; ; 5836 : float ra = 1.0f / a; ; 5837 : float inv_a = 65535.0f * (1 - ra); ; 5838 : pixel[0] = (stbi__uint16)(pixel[0] * ra + inv_a); ; 5839 : pixel[1] = (stbi__uint16)(pixel[1] * ra + inv_a); ; 5840 : pixel[2] = (stbi__uint16)(pixel[2] * ra + inv_a); ; 5841 : } ; 5842 : } ; 5843 : } ; 5844 : else { ; 5845 : for (i = 0; i < w * h; ++i) { ; 5846 : unsigned char* pixel = out + 4 * i; ; 5847 : if (pixel[3] != 0 && pixel[3] != 255) { ; 5848 : float a = pixel[3] / 255.0f; ; 5849 : float ra = 1.0f / a; ; 5850 : float inv_a = 255.0f * (1 - ra); ; 5851 : pixel[0] = (unsigned char)(pixel[0] * ra + inv_a); ; 5852 : pixel[1] = (unsigned char)(pixel[1] * ra + inv_a); ; 5853 : pixel[2] = (unsigned char)(pixel[2] * ra + inv_a); ; 5854 : } ; 5855 : } ; 5856 : } ; 5857 : } ; 5858 : ; 5859 : // convert to desired output format ; 5860 : if (req_comp && req_comp != 4) { ; 5861 : if (ri->bits_per_channel == 16) ; 5862 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, 4, req_comp, w, h); ; 5863 : else ; 5864 : out = stbi__convert_format(out, 4, req_comp, w, h); ; 5865 : if (out == NULL) return out; // stbi__convert_format frees input on failure ; 5866 : } ; 5867 : ; 5868 : if (comp) *comp = 4; ; 5869 : *y = h; ; 5870 : *x = w; ; 5871 : ; 5872 : return out; ; 5873 : } ; 5874 : #endif ; 5875 : ; 5876 : // ************************************************************************************************* ; 5877 : // Softimage PIC loader ; 5878 : // by Tom Seddon ; 5879 : // ; 5880 : // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format ; 5881 : // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ ; 5882 : ; 5883 : #ifndef STBI_NO_PIC ; 5884 : static int stbi__pic_is4(stbi__context* s, const char* str) ; 5885 : { ; 5886 : int i; ; 5887 : for (i = 0; i < 4; ++i) ; 5888 : if (stbi__get8(s) != (stbi_uc)str[i]) ; 5889 : return 0; ; 5890 : ; 5891 : return 1; ; 5892 : } ; 5893 : ; 5894 : static int stbi__pic_test_core(stbi__context* s) ; 5895 : { ; 5896 : int i; ; 5897 : ; 5898 : if (!stbi__pic_is4(s, "\x53\x80\xF6\x34")) ; 5899 : return 0; ; 5900 : ; 5901 : for (i = 0; i < 84; ++i) ; 5902 : stbi__get8(s); ; 5903 : ; 5904 : if (!stbi__pic_is4(s, "PICT")) ; 5905 : return 0; ; 5906 : ; 5907 : return 1; ; 5908 : } ; 5909 : ; 5910 : typedef struct ; 5911 : { ; 5912 : stbi_uc size, type, channel; ; 5913 : } stbi__pic_packet; ; 5914 : ; 5915 : static stbi_uc* stbi__readval(stbi__context* s, int channel, stbi_uc* dest) ; 5916 : { ; 5917 : int mask = 0x80, i; ; 5918 : ; 5919 : for (i = 0; i < 4; ++i, mask >>= 1) { ; 5920 : if (channel & mask) { ; 5921 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "PIC file too short"); ; 5922 : dest[i] = stbi__get8(s); ; 5923 : } ; 5924 : } ; 5925 : ; 5926 : return dest; ; 5927 : } ; 5928 : ; 5929 : static void stbi__copyval(int channel, stbi_uc* dest, const stbi_uc* src) ; 5930 : { ; 5931 : int mask = 0x80, i; ; 5932 : ; 5933 : for (i = 0; i < 4; ++i, mask >>= 1) ; 5934 : if (channel & mask) ; 5935 : dest[i] = src[i]; ; 5936 : } ; 5937 : ; 5938 : static stbi_uc* stbi__pic_load_core(stbi__context* s, int width, int height, int* comp, stbi_uc* result) ; 5939 : { ; 5940 : int act_comp = 0, num_packets = 0, y, chained; ; 5941 : stbi__pic_packet packets[10]; ; 5942 : ; 5943 : // this will (should...) cater for even some bizarre stuff like having data ; 5944 : // for the same channel in multiple packets. ; 5945 : do { ; 5946 : stbi__pic_packet* packet; ; 5947 : ; 5948 : if (num_packets == sizeof(packets) / sizeof(packets[0])) ; 5949 : return stbi__errpuc("bad format", "too many packets"); ; 5950 : ; 5951 : packet = &packets[num_packets++]; ; 5952 : ; 5953 : chained = stbi__get8(s); ; 5954 : packet->size = stbi__get8(s); ; 5955 : packet->type = stbi__get8(s); ; 5956 : packet->channel = stbi__get8(s); ; 5957 : ; 5958 : act_comp |= packet->channel; ; 5959 : ; 5960 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (reading packets)"); ; 5961 : if (packet->size != 8) return stbi__errpuc("bad format", "packet isn't 8bpp"); ; 5962 : } while (chained); ; 5963 : ; 5964 : *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? ; 5965 : ; 5966 : for (y = 0; y < height; ++y) { ; 5967 : int packet_idx; ; 5968 : ; 5969 : for (packet_idx = 0; packet_idx < num_packets; ++packet_idx) { ; 5970 : stbi__pic_packet* packet = &packets[packet_idx]; ; 5971 : stbi_uc* dest = result + y * width * 4; ; 5972 : ; 5973 : switch (packet->type) { ; 5974 : default: ; 5975 : return stbi__errpuc("bad format", "packet has bad compression type"); ; 5976 : ; 5977 : case 0: {//uncompressed ; 5978 : int x; ; 5979 : ; 5980 : for (x = 0; x < width; ++x, dest += 4) ; 5981 : if (!stbi__readval(s, packet->channel, dest)) ; 5982 : return 0; ; 5983 : break; ; 5984 : } ; 5985 : ; 5986 : case 1://Pure RLE ; 5987 : { ; 5988 : int left = width, i; ; 5989 : ; 5990 : while (left > 0) { ; 5991 : stbi_uc count, value[4]; ; 5992 : ; 5993 : count = stbi__get8(s); ; 5994 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pure read count)"); ; 5995 : ; 5996 : if (count > left) ; 5997 : count = (stbi_uc)left; ; 5998 : ; 5999 : if (!stbi__readval(s, packet->channel, value)) return 0; ; 6000 : ; 6001 : for (i = 0; i < count; ++i, dest += 4) ; 6002 : stbi__copyval(packet->channel, dest, value); ; 6003 : left -= count; ; 6004 : } ; 6005 : } ; 6006 : break; ; 6007 : ; 6008 : case 2: {//Mixed RLE ; 6009 : int left = width; ; 6010 : while (left > 0) { ; 6011 : int count = stbi__get8(s), i; ; 6012 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (mixed read count)"); ; 6013 : ; 6014 : if (count >= 128) { // Repeated ; 6015 : stbi_uc value[4]; ; 6016 : ; 6017 : if (count == 128) ; 6018 : count = stbi__get16be(s); ; 6019 : else ; 6020 : count -= 127; ; 6021 : if (count > left) ; 6022 : return stbi__errpuc("bad file", "scanline overrun"); ; 6023 : ; 6024 : if (!stbi__readval(s, packet->channel, value)) ; 6025 : return 0; ; 6026 : ; 6027 : for (i = 0; i < count; ++i, dest += 4) ; 6028 : stbi__copyval(packet->channel, dest, value); ; 6029 : } ; 6030 : else { // Raw ; 6031 : ++count; ; 6032 : if (count > left) return stbi__errpuc("bad file", "scanline overrun"); ; 6033 : ; 6034 : for (i = 0; i < count; ++i, dest += 4) ; 6035 : if (!stbi__readval(s, packet->channel, dest)) ; 6036 : return 0; ; 6037 : } ; 6038 : left -= count; ; 6039 : } ; 6040 : break; ; 6041 : } ; 6042 : } ; 6043 : } ; 6044 : } ; 6045 : ; 6046 : return result; ; 6047 : } ; 6048 : ; 6049 : static void* stbi__pic_load(stbi__context* s, int* px, int* py, int* comp, int req_comp, stbi__result_info* ri) ; 6050 : { ; 6051 : stbi_uc* result; ; 6052 : int i, x, y, internal_comp; ; 6053 : STBI_NOTUSED(ri); ; 6054 : ; 6055 : if (!comp) comp = &internal_comp; ; 6056 : ; 6057 : for (i = 0; i < 92; ++i) ; 6058 : stbi__get8(s); ; 6059 : ; 6060 : x = stbi__get16be(s); ; 6061 : y = stbi__get16be(s); ; 6062 : ; 6063 : if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 6064 : if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); ; 6065 : ; 6066 : if (stbi__at_eof(s)) return stbi__errpuc("bad file", "file too short (pic header)"); ; 6067 : if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); ; 6068 : ; 6069 : stbi__get32be(s); //skip `ratio' ; 6070 : stbi__get16be(s); //skip `fields' ; 6071 : stbi__get16be(s); //skip `pad' ; 6072 : ; 6073 : // intermediate buffer is RGBA ; 6074 : result = (stbi_uc*)stbi__malloc_mad3(x, y, 4, 0); ; 6075 : if (!result) return stbi__errpuc("outofmem", "Out of memory"); ; 6076 : memset(result, 0xff, x * y * 4); ; 6077 : ; 6078 : if (!stbi__pic_load_core(s, x, y, comp, result)) { ; 6079 : STBI_FREE(result); ; 6080 : result = 0; ; 6081 : } ; 6082 : *px = x; ; 6083 : *py = y; ; 6084 : if (req_comp == 0) req_comp = *comp; ; 6085 : result = stbi__convert_format(result, 4, req_comp, x, y); ; 6086 : ; 6087 : return result; ; 6088 : } ; 6089 : ; 6090 : static int stbi__pic_test(stbi__context* s) ; 6091 : { ; 6092 : int r = stbi__pic_test_core(s); ; 6093 : stbi__rewind(s); ; 6094 : return r; ; 6095 : } ; 6096 : #endif ; 6097 : ; 6098 : // ************************************************************************************************* ; 6099 : // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb ; 6100 : ; 6101 : #ifndef STBI_NO_GIF ; 6102 : typedef struct ; 6103 : { ; 6104 : stbi__int16 prefix; ; 6105 : stbi_uc first; ; 6106 : stbi_uc suffix; ; 6107 : } stbi__gif_lzw; ; 6108 : ; 6109 : typedef struct ; 6110 : { ; 6111 : int w, h; ; 6112 : stbi_uc* out; // output buffer (always 4 components) ; 6113 : stbi_uc* background; // The current "background" as far as a gif is concerned ; 6114 : stbi_uc* history; ; 6115 : int flags, bgindex, ratio, transparent, eflags; ; 6116 : stbi_uc pal[256][4]; ; 6117 : stbi_uc lpal[256][4]; ; 6118 : stbi__gif_lzw codes[8192]; ; 6119 : stbi_uc* color_table; ; 6120 : int parse, step; ; 6121 : int lflags; ; 6122 : int start_x, start_y; ; 6123 : int max_x, max_y; ; 6124 : int cur_x, cur_y; ; 6125 : int line_size; ; 6126 : int delay; ; 6127 : } stbi__gif; ; 6128 : ; 6129 : static int stbi__gif_test_raw(stbi__context* s) ; 6130 : { ; 6131 : int sz; ; 6132 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; ; 6133 : sz = stbi__get8(s); ; 6134 : if (sz != '9' && sz != '7') return 0; ; 6135 : if (stbi__get8(s) != 'a') return 0; ; 6136 : return 1; ; 6137 : } ; 6138 : ; 6139 : static int stbi__gif_test(stbi__context* s) ; 6140 : { ; 6141 : int r = stbi__gif_test_raw(s); ; 6142 : stbi__rewind(s); ; 6143 : return r; ; 6144 : } ; 6145 : ; 6146 : static void stbi__gif_parse_colortable(stbi__context* s, stbi_uc pal[256][4], int num_entries, int transp) ; 6147 : { ; 6148 : int i; ; 6149 : for (i = 0; i < num_entries; ++i) { ; 6150 : pal[i][2] = stbi__get8(s); ; 6151 : pal[i][1] = stbi__get8(s); ; 6152 : pal[i][0] = stbi__get8(s); ; 6153 : pal[i][3] = transp == i ? 0 : 255; ; 6154 : } ; 6155 : } ; 6156 : ; 6157 : static int stbi__gif_header(stbi__context* s, stbi__gif* g, int* comp, int is_info) ; 6158 : { ; 6159 : stbi_uc version; ; 6160 : if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') ; 6161 : return stbi__err("not GIF", "Corrupt GIF"); ; 6162 : ; 6163 : version = stbi__get8(s); ; 6164 : if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); ; 6165 : if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); ; 6166 : ; 6167 : stbi__g_failure_reason = ""; ; 6168 : g->w = stbi__get16le(s); ; 6169 : g->h = stbi__get16le(s); ; 6170 : g->flags = stbi__get8(s); ; 6171 : g->bgindex = stbi__get8(s); ; 6172 : g->ratio = stbi__get8(s); ; 6173 : g->transparent = -1; ; 6174 : ; 6175 : if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 6176 : if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large", "Very large image (corrupt?)"); ; 6177 : ; 6178 : if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments ; 6179 : ; 6180 : if (is_info) return 1; ; 6181 : ; 6182 : if (g->flags & 0x80) ; 6183 : stbi__gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); ; 6184 : ; 6185 : return 1; ; 6186 : } ; 6187 : ; 6188 : static int stbi__gif_info_raw(stbi__context* s, int* x, int* y, int* comp) ; 6189 : { ; 6190 : stbi__gif* g = (stbi__gif*)stbi__malloc(sizeof(stbi__gif)); ; 6191 : if (!g) return stbi__err("outofmem", "Out of memory"); ; 6192 : if (!stbi__gif_header(s, g, comp, 1)) { ; 6193 : STBI_FREE(g); ; 6194 : stbi__rewind(s); ; 6195 : return 0; ; 6196 : } ; 6197 : if (x) *x = g->w; ; 6198 : if (y) *y = g->h; ; 6199 : STBI_FREE(g); ; 6200 : return 1; ; 6201 : } ; 6202 : ; 6203 : static void stbi__out_gif_code(stbi__gif* g, stbi__uint16 code) ; 6204 : { ; 6205 : stbi_uc* p, * c; ; 6206 : int idx; ; 6207 : ; 6208 : // recurse to decode the prefixes, since the linked-list is backwards, ; 6209 : // and working backwards through an interleaved image would be nasty ; 6210 : if (g->codes[code].prefix >= 0) ; 6211 : stbi__out_gif_code(g, g->codes[code].prefix); ; 6212 : ; 6213 : if (g->cur_y >= g->max_y) return; ; 6214 : ; 6215 : idx = g->cur_x + g->cur_y; ; 6216 : p = &g->out[idx]; ; 6217 : g->history[idx / 4] = 1; ; 6218 : ; 6219 : c = &g->color_table[g->codes[code].suffix * 4]; ; 6220 : if (c[3] > 128) { // don't render transparent pixels; ; 6221 : p[0] = c[2]; ; 6222 : p[1] = c[1]; ; 6223 : p[2] = c[0]; ; 6224 : p[3] = c[3]; ; 6225 : } ; 6226 : g->cur_x += 4; ; 6227 : ; 6228 : if (g->cur_x >= g->max_x) { ; 6229 : g->cur_x = g->start_x; ; 6230 : g->cur_y += g->step; ; 6231 : ; 6232 : while (g->cur_y >= g->max_y && g->parse > 0) { ; 6233 : g->step = (1 << g->parse) * g->line_size; ; 6234 : g->cur_y = g->start_y + (g->step >> 1); ; 6235 : --g->parse; ; 6236 : } ; 6237 : } ; 6238 : } ; 6239 : ; 6240 : static stbi_uc* stbi__process_gif_raster(stbi__context* s, stbi__gif* g) ; 6241 : { ; 6242 : stbi_uc lzw_cs; ; 6243 : stbi__int32 len, init_code; ; 6244 : stbi__uint32 first; ; 6245 : stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; ; 6246 : stbi__gif_lzw* p; ; 6247 : ; 6248 : lzw_cs = stbi__get8(s); ; 6249 : if (lzw_cs > 12) return NULL; ; 6250 : clear = 1 << lzw_cs; ; 6251 : first = 1; ; 6252 : codesize = lzw_cs + 1; ; 6253 : codemask = (1 << codesize) - 1; ; 6254 : bits = 0; ; 6255 : valid_bits = 0; ; 6256 : for (init_code = 0; init_code < clear; init_code++) { ; 6257 : g->codes[init_code].prefix = -1; ; 6258 : g->codes[init_code].first = (stbi_uc)init_code; ; 6259 : g->codes[init_code].suffix = (stbi_uc)init_code; ; 6260 : } ; 6261 : ; 6262 : // support no starting clear code ; 6263 : avail = clear + 2; ; 6264 : oldcode = -1; ; 6265 : ; 6266 : len = 0; ; 6267 : for (;;) { ; 6268 : if (valid_bits < codesize) { ; 6269 : if (len == 0) { ; 6270 : len = stbi__get8(s); // start new block ; 6271 : if (len == 0) ; 6272 : return g->out; ; 6273 : } ; 6274 : --len; ; 6275 : bits |= (stbi__int32)stbi__get8(s) << valid_bits; ; 6276 : valid_bits += 8; ; 6277 : } ; 6278 : else { ; 6279 : stbi__int32 code = bits & codemask; ; 6280 : bits >>= codesize; ; 6281 : valid_bits -= codesize; ; 6282 : // @OPTIMIZE: is there some way we can accelerate the non-clear path? ; 6283 : if (code == clear) { // clear code ; 6284 : codesize = lzw_cs + 1; ; 6285 : codemask = (1 << codesize) - 1; ; 6286 : avail = clear + 2; ; 6287 : oldcode = -1; ; 6288 : first = 0; ; 6289 : } ; 6290 : else if (code == clear + 1) { // end of stream code ; 6291 : stbi__skip(s, len); ; 6292 : while ((len = stbi__get8(s)) > 0) ; 6293 : stbi__skip(s, len); ; 6294 : return g->out; ; 6295 : } ; 6296 : else if (code <= avail) { ; 6297 : if (first) { ; 6298 : return stbi__errpuc("no clear code", "Corrupt GIF"); ; 6299 : } ; 6300 : ; 6301 : if (oldcode >= 0) { ; 6302 : p = &g->codes[avail++]; ; 6303 : if (avail > 8192) { ; 6304 : return stbi__errpuc("too many codes", "Corrupt GIF"); ; 6305 : } ; 6306 : ; 6307 : p->prefix = (stbi__int16)oldcode; ; 6308 : p->first = g->codes[oldcode].first; ; 6309 : p->suffix = (code == avail) ? p->first : g->codes[code].first; ; 6310 : } ; 6311 : else if (code == avail) ; 6312 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); ; 6313 : ; 6314 : stbi__out_gif_code(g, (stbi__uint16)code); ; 6315 : ; 6316 : if ((avail & codemask) == 0 && avail <= 0x0FFF) { ; 6317 : codesize++; ; 6318 : codemask = (1 << codesize) - 1; ; 6319 : } ; 6320 : ; 6321 : oldcode = code; ; 6322 : } ; 6323 : else { ; 6324 : return stbi__errpuc("illegal code in raster", "Corrupt GIF"); ; 6325 : } ; 6326 : } ; 6327 : } ; 6328 : } ; 6329 : ; 6330 : // this function is designed to support animated gifs, although stb_image doesn't support it ; 6331 : // two back is the image from two frames ago, used for a very specific disposal format ; 6332 : static stbi_uc* stbi__gif_load_next(stbi__context* s, stbi__gif* g, int* comp, int req_comp, stbi_uc* two_back) ; 6333 : { ; 6334 : int dispose; ; 6335 : int first_frame; ; 6336 : int pi; ; 6337 : int pcount; ; 6338 : STBI_NOTUSED(req_comp); ; 6339 : ; 6340 : // on first frame, any non-written pixels get the background colour (non-transparent) ; 6341 : first_frame = 0; ; 6342 : if (g->out == 0) { ; 6343 : if (!stbi__gif_header(s, g, comp, 0)) return 0; // stbi__g_failure_reason set by stbi__gif_header ; 6344 : if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) ; 6345 : return stbi__errpuc("too large", "GIF image is too large"); ; 6346 : pcount = g->w * g->h; ; 6347 : g->out = (stbi_uc*)stbi__malloc(4 * pcount); ; 6348 : g->background = (stbi_uc*)stbi__malloc(4 * pcount); ; 6349 : g->history = (stbi_uc*)stbi__malloc(pcount); ; 6350 : if (!g->out || !g->background || !g->history) ; 6351 : return stbi__errpuc("outofmem", "Out of memory"); ; 6352 : ; 6353 : // image is treated as "transparent" at the start - ie, nothing overwrites the current background; ; 6354 : // background colour is only used for pixels that are not rendered first frame, after that "background" ; 6355 : // color refers to the color that was there the previous frame. ; 6356 : memset(g->out, 0x00, 4 * pcount); ; 6357 : memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) ; 6358 : memset(g->history, 0x00, pcount); // pixels that were affected previous frame ; 6359 : first_frame = 1; ; 6360 : } ; 6361 : else { ; 6362 : // second frame - how do we dispose of the previous one? ; 6363 : dispose = (g->eflags & 0x1C) >> 2; ; 6364 : pcount = g->w * g->h; ; 6365 : ; 6366 : if ((dispose == 3) && (two_back == 0)) { ; 6367 : dispose = 2; // if I don't have an image to revert back to, default to the old background ; 6368 : } ; 6369 : ; 6370 : if (dispose == 3) { // use previous graphic ; 6371 : for (pi = 0; pi < pcount; ++pi) { ; 6372 : if (g->history[pi]) { ; 6373 : memcpy(&g->out[pi * 4], &two_back[pi * 4], 4); ; 6374 : } ; 6375 : } ; 6376 : } ; 6377 : else if (dispose == 2) { ; 6378 : // restore what was changed last frame to background before that frame; ; 6379 : for (pi = 0; pi < pcount; ++pi) { ; 6380 : if (g->history[pi]) { ; 6381 : memcpy(&g->out[pi * 4], &g->background[pi * 4], 4); ; 6382 : } ; 6383 : } ; 6384 : } ; 6385 : else { ; 6386 : // This is a non-disposal case eithe way, so just ; 6387 : // leave the pixels as is, and they will become the new background ; 6388 : // 1: do not dispose ; 6389 : // 0: not specified. ; 6390 : } ; 6391 : ; 6392 : // background is what out is after the undoing of the previou frame; ; 6393 : memcpy(g->background, g->out, 4 * g->w * g->h); ; 6394 : } ; 6395 : ; 6396 : // clear my history; ; 6397 : memset(g->history, 0x00, g->w * g->h); // pixels that were affected previous frame ; 6398 : ; 6399 : for (;;) { ; 6400 : int tag = stbi__get8(s); ; 6401 : switch (tag) { ; 6402 : case 0x2C: /* Image Descriptor */ ; 6403 : { ; 6404 : stbi__int32 x, y, w, h; ; 6405 : stbi_uc* o; ; 6406 : ; 6407 : x = stbi__get16le(s); ; 6408 : y = stbi__get16le(s); ; 6409 : w = stbi__get16le(s); ; 6410 : h = stbi__get16le(s); ; 6411 : if (((x + w) > (g->w)) || ((y + h) > (g->h))) ; 6412 : return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); ; 6413 : ; 6414 : g->line_size = g->w * 4; ; 6415 : g->start_x = x * 4; ; 6416 : g->start_y = y * g->line_size; ; 6417 : g->max_x = g->start_x + w * 4; ; 6418 : g->max_y = g->start_y + h * g->line_size; ; 6419 : g->cur_x = g->start_x; ; 6420 : g->cur_y = g->start_y; ; 6421 : ; 6422 : // if the width of the specified rectangle is 0, that means ; 6423 : // we may not see *any* pixels or the image is malformed; ; 6424 : // to make sure this is caught, move the current y down to ; 6425 : // max_y (which is what out_gif_code checks). ; 6426 : if (w == 0) ; 6427 : g->cur_y = g->max_y; ; 6428 : ; 6429 : g->lflags = stbi__get8(s); ; 6430 : ; 6431 : if (g->lflags & 0x40) { ; 6432 : g->step = 8 * g->line_size; // first interlaced spacing ; 6433 : g->parse = 3; ; 6434 : } ; 6435 : else { ; 6436 : g->step = g->line_size; ; 6437 : g->parse = 0; ; 6438 : } ; 6439 : ; 6440 : if (g->lflags & 0x80) { ; 6441 : stbi__gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); ; 6442 : g->color_table = (stbi_uc*)g->lpal; ; 6443 : } ; 6444 : else if (g->flags & 0x80) { ; 6445 : g->color_table = (stbi_uc*)g->pal; ; 6446 : } ; 6447 : else ; 6448 : return stbi__errpuc("missing color table", "Corrupt GIF"); ; 6449 : ; 6450 : o = stbi__process_gif_raster(s, g); ; 6451 : if (!o) return NULL; ; 6452 : ; 6453 : // if this was the first frame, ; 6454 : pcount = g->w * g->h; ; 6455 : if (first_frame && (g->bgindex > 0)) { ; 6456 : // if first frame, any pixel not drawn to gets the background color ; 6457 : for (pi = 0; pi < pcount; ++pi) { ; 6458 : if (g->history[pi] == 0) { ; 6459 : g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; ; 6460 : memcpy(&g->out[pi * 4], &g->pal[g->bgindex], 4); ; 6461 : } ; 6462 : } ; 6463 : } ; 6464 : ; 6465 : return o; ; 6466 : } ; 6467 : ; 6468 : case 0x21: // Comment Extension. ; 6469 : { ; 6470 : int len; ; 6471 : int ext = stbi__get8(s); ; 6472 : if (ext == 0xF9) { // Graphic Control Extension. ; 6473 : len = stbi__get8(s); ; 6474 : if (len == 4) { ; 6475 : g->eflags = stbi__get8(s); ; 6476 : g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. ; 6477 : ; 6478 : // unset old transparent ; 6479 : if (g->transparent >= 0) { ; 6480 : g->pal[g->transparent][3] = 255; ; 6481 : } ; 6482 : if (g->eflags & 0x01) { ; 6483 : g->transparent = stbi__get8(s); ; 6484 : if (g->transparent >= 0) { ; 6485 : g->pal[g->transparent][3] = 0; ; 6486 : } ; 6487 : } ; 6488 : else { ; 6489 : // don't need transparent ; 6490 : stbi__skip(s, 1); ; 6491 : g->transparent = -1; ; 6492 : } ; 6493 : } ; 6494 : else { ; 6495 : stbi__skip(s, len); ; 6496 : break; ; 6497 : } ; 6498 : } ; 6499 : while ((len = stbi__get8(s)) != 0) { ; 6500 : stbi__skip(s, len); ; 6501 : } ; 6502 : break; ; 6503 : } ; 6504 : ; 6505 : case 0x3B: // gif stream termination code ; 6506 : return (stbi_uc*)s; // using '1' causes warning on some compilers ; 6507 : ; 6508 : default: ; 6509 : return stbi__errpuc("unknown code", "Corrupt GIF"); ; 6510 : } ; 6511 : } ; 6512 : } ; 6513 : ; 6514 : static void* stbi__load_gif_main_outofmem(stbi__gif* g, stbi_uc* out, int** delays) ; 6515 : { ; 6516 : STBI_FREE(g->out); ; 6517 : STBI_FREE(g->history); ; 6518 : STBI_FREE(g->background); ; 6519 : ; 6520 : if (out) STBI_FREE(out); ; 6521 : if (delays && *delays) STBI_FREE(*delays); ; 6522 : return stbi__errpuc("outofmem", "Out of memory"); ; 6523 : } ; 6524 : ; 6525 : static void* stbi__load_gif_main(stbi__context* s, int** delays, int* x, int* y, int* z, int* comp, int req_comp) ; 6526 : { ; 6527 : if (stbi__gif_test(s)) { ; 6528 : int layers = 0; ; 6529 : stbi_uc* u = 0; ; 6530 : stbi_uc* out = 0; ; 6531 : stbi_uc* two_back = 0; ; 6532 : stbi__gif g; ; 6533 : int stride; ; 6534 : int out_size = 0; ; 6535 : int delays_size = 0; ; 6536 : ; 6537 : STBI_NOTUSED(out_size); ; 6538 : STBI_NOTUSED(delays_size); ; 6539 : ; 6540 : memset(&g, 0, sizeof(g)); ; 6541 : if (delays) { ; 6542 : *delays = 0; ; 6543 : } ; 6544 : ; 6545 : do { ; 6546 : u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); ; 6547 : if (u == (stbi_uc*)s) u = 0; // end of animated gif marker ; 6548 : ; 6549 : if (u) { ; 6550 : *x = g.w; ; 6551 : *y = g.h; ; 6552 : ++layers; ; 6553 : stride = g.w * g.h * 4; ; 6554 : ; 6555 : if (out) { ; 6556 : void* tmp = (stbi_uc*)STBI_REALLOC_SIZED(out, out_size, layers * stride); ; 6557 : if (!tmp) ; 6558 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6559 : else { ; 6560 : out = (stbi_uc*)tmp; ; 6561 : out_size = layers * stride; ; 6562 : } ; 6563 : ; 6564 : if (delays) { ; 6565 : int* new_delays = (int*)STBI_REALLOC_SIZED(*delays, delays_size, sizeof(int) * layers); ; 6566 : if (!new_delays) ; 6567 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6568 : *delays = new_delays; ; 6569 : delays_size = layers * sizeof(int); ; 6570 : } ; 6571 : } ; 6572 : else { ; 6573 : out = (stbi_uc*)stbi__malloc(layers * stride); ; 6574 : if (!out) ; 6575 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6576 : out_size = layers * stride; ; 6577 : if (delays) { ; 6578 : *delays = (int*)stbi__malloc(layers * sizeof(int)); ; 6579 : if (!*delays) ; 6580 : return stbi__load_gif_main_outofmem(&g, out, delays); ; 6581 : delays_size = layers * sizeof(int); ; 6582 : } ; 6583 : } ; 6584 : memcpy(out + ((layers - 1) * stride), u, stride); ; 6585 : if (layers >= 2) { ; 6586 : two_back = out - 2 * stride; ; 6587 : } ; 6588 : ; 6589 : if (delays) { ; 6590 : (*delays)[layers - 1U] = g.delay; ; 6591 : } ; 6592 : } ; 6593 : } while (u != 0); ; 6594 : ; 6595 : // free temp buffer; ; 6596 : STBI_FREE(g.out); ; 6597 : STBI_FREE(g.history); ; 6598 : STBI_FREE(g.background); ; 6599 : ; 6600 : // do the final conversion after loading everything; ; 6601 : if (req_comp && req_comp != 4) ; 6602 : out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); ; 6603 : ; 6604 : *z = layers; ; 6605 : return out; ; 6606 : } ; 6607 : else { ; 6608 : return stbi__errpuc("not GIF", "Image was not as a gif type."); ; 6609 : } ; 6610 : } ; 6611 : ; 6612 : static void* stbi__gif_load(stbi__context* s, int* x, int* y, int* comp, int req_comp, stbi__result_info* ri) ; 6613 : { ; 6614 : stbi_uc* u = 0; ; 6615 : stbi__gif g; ; 6616 : memset(&g, 0, sizeof(g)); ; 6617 : STBI_NOTUSED(ri); ; 6618 : ; 6619 : u = stbi__gif_load_next(s, &g, comp, req_comp, 0); ; 6620 : if (u == (stbi_uc*)s) u = 0; // end of animated gif marker ; 6621 : if (u) { ; 6622 : *x = g.w; ; 6623 : *y = g.h; ; 6624 : ; 6625 : // moved conversion to after successful load so that the same ; 6626 : // can be done for multiple frames. ; 6627 : if (req_comp && req_comp != 4) ; 6628 : u = stbi__convert_format(u, 4, req_comp, g.w, g.h); ; 6629 : } ; 6630 : else if (g.out) { ; 6631 : // if there was an error and we allocated an image buffer, free it! ; 6632 : STBI_FREE(g.out); ; 6633 : } ; 6634 : ; 6635 : // free buffers needed for multiple frame loading; ; 6636 : STBI_FREE(g.history); ; 6637 : STBI_FREE(g.background); ; 6638 : ; 6639 : return u; ; 6640 : } ; 6641 : ; 6642 : static int stbi__gif_info(stbi__context* s, int* x, int* y, int* comp) ; 6643 : { ; 6644 : return stbi__gif_info_raw(s, x, y, comp); ; 6645 : } ; 6646 : #endif ; 6647 : ; 6648 : // ************************************************************************************************* ; 6649 : // Radiance RGBE HDR loader ; 6650 : // originally by Nicolas Schulz ; 6651 : #ifndef STBI_NO_HDR ; 6652 : static int stbi__hdr_test_core(stbi__context* s, const char* signature) ; 6653 : { ; 6654 : int i; ; 6655 : for (i = 0; signature[i]; ++i) 000dc 48 ff c6 inc rsi 000df 80 3e 00 cmp BYTE PTR [rsi], 0 000e2 75 bc jne SHORT $LL21@stbi__hdr_ ; 6658 : stbi__rewind(s); ; 6659 : return 1; 000e4 b8 01 00 00 00 mov eax, 1 000e9 eb 02 jmp SHORT $LN18@stbi__hdr_ $LN35@stbi__hdr_: ; 6657 : return 0; 000eb 33 c0 xor eax, eax $LN18@stbi__hdr_: ; 6664 : int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); ; 6665 : stbi__rewind(s); ; 6666 : if (!r) { ; 6667 : r = stbi__hdr_test_core(s, "#?RGBE\n"); ; 6668 : stbi__rewind(s); ; 6669 : } ; 6670 : return r; 000ed 48 8b 97 d0 00 00 00 mov rdx, QWORD PTR [rdi+208] 000f4 48 8b 8f d8 00 00 00 mov rcx, QWORD PTR [rdi+216] 000fb 48 89 13 mov QWORD PTR [rbx], rdx 000fe 48 89 8f c8 00 00 00 mov QWORD PTR [rdi+200], rcx ; 6671 : } 00105 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0010a 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 0010f 48 8b 7c 24 40 mov rdi, QWORD PTR [rsp+64] 00114 48 83 c4 20 add rsp, 32 ; 00000020H 00118 41 5e pop r14 0011a c3 ret 0 stbi__hdr_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_gettoken _TEXT SEGMENT z$ = 64 buffer$ = 72 stbi__hdr_gettoken PROC ; COMDAT ; 6675 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 57 push rdi 00010 41 56 push r14 00012 41 57 push r15 00014 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 00018 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 6676 : int len = 0; 0001f 45 33 f6 xor r14d, r14d 00022 4c 8b fa mov r15, rdx 00025 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00028 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0002f 73 0f jae SHORT $LN9@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00031 0f b6 38 movzx edi, BYTE PTR [rax] 00034 48 ff c0 inc rax 00037 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax 0003e eb 27 jmp SHORT $LN62@stbi__hdr_ $LN9@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 00040 44 39 71 30 cmp DWORD PTR [rcx+48], r14d 00044 74 1e je SHORT $LN10@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00046 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0004b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00052 48 8b cb mov rcx, rbx 00055 0f b6 38 movzx edi, BYTE PTR [rax] 00058 48 ff c0 inc rax 0005b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00062 eb 03 jmp SHORT $LN62@stbi__hdr_ $LN10@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00064 40 32 ff xor dil, dil $LN62@stbi__hdr_: ; 6677 : char c = '\0'; ; 6678 : ; 6679 : c = (char)stbi__get8(z); 00067 b8 30 00 00 00 mov eax, 48 ; 00000030H 0006c 49 8b f6 mov rsi, r14 0006f 48 8d 2c 08 lea rbp, QWORD PTR [rax+rcx] $LL2@stbi__hdr_: ; 1091 : if (s->io.read) { 00073 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00078 74 15 je SHORT $LN42@stbi__hdr_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0007a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0007e ff 53 20 call QWORD PTR [rbx+32] 00081 85 c0 test eax, eax 00083 74 1e je SHORT $LN45@stbi__hdr_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00085 83 7d 00 00 cmp DWORD PTR [rbp], 0 00089 0f 84 e6 00 00 00 je $LN49@stbi__hdr_ $LN42@stbi__hdr_: ; 6680 : ; 6681 : while (!stbi__at_eof(z) && c != '\n') { 0008f 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00096 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 0009d 0f 83 d2 00 00 00 jae $LN49@stbi__hdr_ $LN45@stbi__hdr_: 000a3 40 80 ff 0a cmp dil, 10 000a7 0f 84 c8 00 00 00 je $LN49@stbi__hdr_ ; 6682 : buffer[len++] = c; 000ad 42 88 3c 3e mov BYTE PTR [rsi+r15], dil 000b1 41 ff c6 inc r14d 000b4 48 ff c6 inc rsi ; 6683 : if (len == STBI__HDR_BUFLEN - 1) { 000b7 48 81 fe ff 03 00 00 cmp rsi, 1023 ; 000003ffH 000be 74 4e je SHORT $LN41@stbi__hdr_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 000c0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000c7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000ce 73 0f jae SHORT $LN27@stbi__hdr_ ; 1078 : return *s->img_buffer++; 000d0 0f b6 38 movzx edi, BYTE PTR [rax] 000d3 48 ff c0 inc rax 000d6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000dd eb 94 jmp SHORT $LL2@stbi__hdr_ $LN27@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 000df 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000e3 74 21 je SHORT $LN28@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 000e5 48 8b cb mov rcx, rbx 000e8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000ed 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000f4 0f b6 38 movzx edi, BYTE PTR [rax] 000f7 48 ff c0 inc rax 000fa 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00101 e9 6d ff ff ff jmp $LL2@stbi__hdr_ $LN28@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00106 40 32 ff xor dil, dil ; 6686 : ; ; 6687 : break; ; 6688 : } ; 6689 : c = (char)stbi__get8(z); ; 6690 : } 00109 e9 65 ff ff ff jmp $LL2@stbi__hdr_ $LN41@stbi__hdr_: 0010e 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] $LL4@stbi__hdr_: ; 1091 : if (s->io.read) { 00112 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00117 74 10 je SHORT $LN43@stbi__hdr_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 00119 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0011d ff 53 20 call QWORD PTR [rbx+32] 00120 85 c0 test eax, eax 00122 74 15 je SHORT $LN44@stbi__hdr_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00124 83 3f 00 cmp DWORD PTR [rdi], 0 00127 74 4c je SHORT $LN49@stbi__hdr_ $LN43@stbi__hdr_: ; 6684 : // flush to end of line ; 6685 : while (!stbi__at_eof(z) && stbi__get8(z) != '\n') 00129 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00130 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 00137 73 3c jae SHORT $LN49@stbi__hdr_ $LN44@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00139 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00140 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00147 73 06 jae SHORT $LN23@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00149 48 8d 7b 30 lea rdi, QWORD PTR [rbx+48] 0014d eb 14 jmp SHORT $LN63@stbi__hdr_ $LN23@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 0014f 83 3f 00 cmp DWORD PTR [rdi], 0 00152 74 be je SHORT $LL4@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00154 48 8b cb mov rcx, rbx 00157 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0015c 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN63@stbi__hdr_: ; 6684 : // flush to end of line ; 6685 : while (!stbi__at_eof(z) && stbi__get8(z) != '\n') 00163 0f b6 08 movzx ecx, BYTE PTR [rax] 00166 48 ff c0 inc rax 00169 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00170 80 f9 0a cmp cl, 10 00173 75 9d jne SHORT $LL4@stbi__hdr_ $LN49@stbi__hdr_: ; 6691 : ; 6692 : buffer[len] = 0; ; 6693 : return buffer; ; 6694 : } 00175 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 0017a 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 0017f 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 00184 49 63 c6 movsxd rax, r14d 00187 42 c6 04 38 00 mov BYTE PTR [rax+r15], 0 0018c 49 8b c7 mov rax, r15 0018f 48 83 c4 20 add rsp, 32 ; 00000020H 00193 41 5f pop r15 00195 41 5e pop r14 00197 5f pop rdi 00198 c3 ret 0 stbi__hdr_gettoken ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_convert _TEXT SEGMENT output$ = 48 input$ = 56 req_comp$ = 64 stbi__hdr_convert PROC ; COMDAT ; 6697 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 74 24 10 mov QWORD PTR [rsp+16], rsi 0000a 57 push rdi 0000b 48 83 ec 20 sub rsp, 32 ; 00000020H ; 6698 : if (input[3] != 0) { 0000f 0f b6 42 03 movzx eax, BYTE PTR [rdx+3] 00013 41 8b d8 mov ebx, r8d 00016 48 8b f2 mov rsi, rdx 00019 48 8b f9 mov rdi, rcx 0001c 84 c0 test al, al 0001e 0f 84 bc 00 00 00 je $LN4@stbi__hdr_ ; 6699 : float f1; ; 6700 : // Exponent ; 6701 : f1 = (float)ldexp(1.0f, input[3] - (int)(128 + 8)); 00024 f2 0f 10 05 00 00 00 00 movsd xmm0, QWORD PTR __real@3ff0000000000000 0002c 8d 90 78 ff ff ff lea edx, DWORD PTR [rax-136] 00032 ff 15 00 00 00 00 call QWORD PTR __imp_ldexp 00038 0f 57 d2 xorps xmm2, xmm2 0003b f2 0f 5a d0 cvtsd2ss xmm2, xmm0 ; 6702 : if (req_comp <= 2) 0003f 83 fb 02 cmp ebx, 2 00042 7f 46 jg SHORT $LN6@stbi__hdr_ ; 6703 : output[0] = (input[0] + input[1] + input[2]) * f1 / 3; 00044 0f b6 46 01 movzx eax, BYTE PTR [rsi+1] 00048 0f b6 4e 02 movzx ecx, BYTE PTR [rsi+2] 0004c 03 c8 add ecx, eax 0004e 0f b6 06 movzx eax, BYTE PTR [rsi] 00051 03 c8 add ecx, eax 00053 66 0f 6e c1 movd xmm0, ecx 00057 0f 5b c0 cvtdq2ps xmm0, xmm0 0005a f3 0f 59 c2 mulss xmm0, xmm2 0005e f3 0f 5e 05 00 00 00 00 divss xmm0, DWORD PTR __real@40400000 00066 f3 0f 11 07 movss DWORD PTR [rdi], xmm0 ; 6708 : } ; 6709 : if (req_comp == 2) output[1] = 1; 0006a 83 fb 02 cmp ebx, 2 0006d 0f 85 ab 00 00 00 jne $LN2@stbi__hdr_ 00073 c7 47 04 00 00 80 3f mov DWORD PTR [rdi+4], 1065353216 ; 3f800000H ; 6719 : break; ; 6720 : } ; 6721 : } ; 6722 : } 0007a 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 0007f 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 00084 48 83 c4 20 add rsp, 32 ; 00000020H 00088 5f pop rdi 00089 c3 ret 0 $LN6@stbi__hdr_: ; 6704 : else { ; 6705 : output[0] = input[0] * f1; 0008a 0f b6 06 movzx eax, BYTE PTR [rsi] 0008d 66 0f 6e c0 movd xmm0, eax 00091 0f 5b c0 cvtdq2ps xmm0, xmm0 00094 f3 0f 59 c2 mulss xmm0, xmm2 00098 f3 0f 11 07 movss DWORD PTR [rdi], xmm0 ; 6706 : output[1] = input[1] * f1; 0009c 0f b6 46 01 movzx eax, BYTE PTR [rsi+1] 000a0 66 0f 6e c8 movd xmm1, eax 000a4 0f 5b c9 cvtdq2ps xmm1, xmm1 000a7 f3 0f 59 ca mulss xmm1, xmm2 000ab f3 0f 11 4f 04 movss DWORD PTR [rdi+4], xmm1 ; 6707 : output[2] = input[2] * f1; 000b0 0f b6 46 02 movzx eax, BYTE PTR [rsi+2] 000b4 66 0f 6e c0 movd xmm0, eax 000b8 0f 5b c0 cvtdq2ps xmm0, xmm0 000bb f3 0f 59 c2 mulss xmm0, xmm2 000bf f3 0f 11 47 08 movss DWORD PTR [rdi+8], xmm0 ; 6710 : if (req_comp == 4) output[3] = 1; 000c4 83 fb 04 cmp ebx, 4 000c7 75 55 jne SHORT $LN2@stbi__hdr_ 000c9 c7 47 0c 00 00 80 3f mov DWORD PTR [rdi+12], 1065353216 ; 3f800000H ; 6719 : break; ; 6720 : } ; 6721 : } ; 6722 : } 000d0 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000d5 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 000da 48 83 c4 20 add rsp, 32 ; 00000020H 000de 5f pop rdi 000df c3 ret 0 $LN4@stbi__hdr_: ; 6711 : } ; 6712 : else { ; 6713 : switch (req_comp) { 000e0 83 eb 01 sub ebx, 1 000e3 74 35 je SHORT $LN13@stbi__hdr_ 000e5 83 eb 01 sub ebx, 1 000e8 74 29 je SHORT $LN12@stbi__hdr_ 000ea 83 eb 01 sub ebx, 1 000ed 74 0c je SHORT $LN11@stbi__hdr_ 000ef 83 fb 01 cmp ebx, 1 000f2 75 2a jne SHORT $LN2@stbi__hdr_ ; 6714 : case 4: output[3] = 1; /* fallthrough */ 000f4 c7 41 0c 00 00 80 3f mov DWORD PTR [rcx+12], 1065353216 ; 3f800000H $LN11@stbi__hdr_: ; 6715 : case 3: output[0] = output[1] = output[2] = 0; 000fb 33 c0 xor eax, eax 000fd 48 89 41 04 mov QWORD PTR [rcx+4], rax ; 6719 : break; ; 6720 : } ; 6721 : } ; 6722 : } 00101 89 01 mov DWORD PTR [rcx], eax 00103 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00108 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 0010d 48 83 c4 20 add rsp, 32 ; 00000020H 00111 5f pop rdi 00112 c3 ret 0 $LN12@stbi__hdr_: ; 6716 : break; ; 6717 : case 2: output[1] = 1; /* fallthrough */ 00113 c7 41 04 00 00 80 3f mov DWORD PTR [rcx+4], 1065353216 ; 3f800000H $LN13@stbi__hdr_: ; 6718 : case 1: output[0] = 0; 0011a 33 c0 xor eax, eax ; 6719 : break; ; 6720 : } ; 6721 : } ; 6722 : } 0011c 89 01 mov DWORD PTR [rcx], eax $LN2@stbi__hdr_: 0011e 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 00123 48 8b 74 24 38 mov rsi, QWORD PTR [rsp+56] 00128 48 83 c4 20 add rsp, 32 ; 00000020H 0012c 5f pop rdi 0012d c3 ret 0 stbi__hdr_convert ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__hdr_load _TEXT SEGMENT scanline$1$ = 32 hdr_data$1$ = 40 width$1$ = 48 j$1$ = 52 tv1712 = 56 height$1$ = 60 tv1792 = 64 token$ = 72 tv1713 = 80 rgbe$17 = 80 rgbe$18 = 80 buffer$ = 96 __$ArrayPad$ = 1120 s$ = 1216 x$ = 1224 y$ = 1232 comp$ = 1240 req_comp$ = 1248 ri$dead$ = 1256 stbi__hdr_load PROC ; COMDAT ; 6725 : { 00000 40 55 push rbp 00002 53 push rbx 00003 56 push rsi 00004 57 push rdi 00005 41 54 push r12 00007 41 55 push r13 00009 41 56 push r14 0000b 41 57 push r15 0000d 48 8d ac 24 88 fc ff ff lea rbp, QWORD PTR [rsp-888] 00015 48 81 ec 78 04 00 00 sub rsp, 1144 ; 00000478H 0001c 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00023 48 33 c4 xor rax, rsp 00026 48 89 85 60 03 00 00 mov QWORD PTR __$ArrayPad$[rbp-256], rax 0002d 44 8b bd e0 03 00 00 mov r15d, DWORD PTR req_comp$[rbp-256] 00034 4c 8b e2 mov r12, rdx ; 6726 : char buffer[STBI__HDR_BUFLEN]; ; 6727 : char* token; ; 6728 : int valid = 0; ; 6729 : int width, height; ; 6730 : stbi_uc* scanline; ; 6731 : float* hdr_data; ; 6732 : int len; ; 6733 : unsigned char count, value; ; 6734 : int i, j, k, c1, c2, z; ; 6735 : const char* headerToken; ; 6736 : STBI_NOTUSED(ri); ; 6737 : ; 6738 : // Check identifier ; 6739 : headerToken = stbi__hdr_gettoken(s, buffer); 00037 48 8d 54 24 60 lea rdx, QWORD PTR buffer$[rsp] 0003c 4d 8b f1 mov r14, r9 0003f 4d 8b e8 mov r13, r8 00042 48 8b d9 mov rbx, rcx 00045 33 ff xor edi, edi 00047 e8 00 00 00 00 call stbi__hdr_gettoken ; 6740 : if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) 0004c 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0L@NCPEAJBD@?$CD?$DPRADIANCE@ 00053 48 8b c8 mov rcx, rax 00056 48 8b f0 mov rsi, rax 00059 e8 00 00 00 00 call strcmp 0005e 85 c0 test eax, eax 00060 74 25 je SHORT $LN30@stbi__hdr_ 00062 33 c9 xor ecx, ecx 00064 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_06NDOKKIDJ@?$CD?$DPRGBE@ 0006b 0f 1f 44 00 00 npad 5 $LL248@stbi__hdr_: 00070 0f b6 04 0e movzx eax, BYTE PTR [rsi+rcx] 00074 48 ff c1 inc rcx 00077 3a 44 0a ff cmp al, BYTE PTR [rdx+rcx-1] 0007b 0f 85 af 00 00 00 jne $LN249@stbi__hdr_ 00081 48 83 f9 07 cmp rcx, 7 00085 75 e9 jne SHORT $LL248@stbi__hdr_ $LN30@stbi__hdr_: ; 6742 : ; 6743 : // Parse header ; 6744 : for (;;) { ; 6745 : token = stbi__hdr_gettoken(s, buffer); 00087 48 8d 54 24 60 lea rdx, QWORD PTR buffer$[rsp] 0008c 48 8b cb mov rcx, rbx 0008f e8 00 00 00 00 call stbi__hdr_gettoken 00094 48 89 44 24 48 mov QWORD PTR token$[rsp], rax ; 6746 : if (token[0] == 0) break; 00099 40 38 38 cmp BYTE PTR [rax], dil 0009c 0f 84 b4 07 00 00 je $LN224@stbi__hdr_ 000a2 be 01 00 00 00 mov esi, 1 000a7 66 0f 1f 84 00 00 00 00 00 npad 9 $LL2@stbi__hdr_: ; 6747 : if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; 000b0 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BH@JFGBLLKC@FORMAT?$DN32?9bit_rle_rgbe@ 000b7 48 8b c8 mov rcx, rax 000ba e8 00 00 00 00 call strcmp 000bf 85 c0 test eax, eax 000c1 48 8d 54 24 60 lea rdx, QWORD PTR buffer$[rsp] 000c6 48 8b cb mov rcx, rbx 000c9 0f 44 fe cmove edi, esi 000cc e8 00 00 00 00 call stbi__hdr_gettoken 000d1 48 89 44 24 48 mov QWORD PTR token$[rsp], rax 000d6 80 38 00 cmp BYTE PTR [rax], 0 000d9 75 d5 jne SHORT $LL2@stbi__hdr_ ; 6748 : } ; 6749 : ; 6750 : if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); 000db 85 ff test edi, edi 000dd 0f 84 73 07 00 00 je $LN224@stbi__hdr_ ; 6751 : ; 6752 : // Parse width and height ; 6753 : // can't use sscanf() if we're not using stdio! ; 6754 : token = stbi__hdr_gettoken(s, buffer); 000e3 48 8d 54 24 60 lea rdx, QWORD PTR buffer$[rsp] 000e8 48 8b cb mov rcx, rbx 000eb e8 00 00 00 00 call stbi__hdr_gettoken ; 6755 : if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); 000f0 bf 03 00 00 00 mov edi, 3 000f5 48 89 44 24 48 mov QWORD PTR token$[rsp], rax 000fa 44 8b c7 mov r8d, edi 000fd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_03HKAKGGJN@?9Y?5@ 00104 48 8b c8 mov rcx, rax 00107 ff 15 00 00 00 00 call QWORD PTR __imp_strncmp 0010d 85 c0 test eax, eax 0010f 74 3e je SHORT $LN34@stbi__hdr_ $LN332@stbi__hdr_: ; 6855 : } 00111 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00117 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00120 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00124 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BI@DCNDPIOH@unsupported?5data?5layout@ 0012b e9 40 07 00 00 jmp $LN327@stbi__hdr_ $LN249@stbi__hdr_: ; 431 : stbi__g_failure_reason = str; 00130 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00136 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0013f 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00143 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07NCIOKENI@not?5HDR@ ; 6741 : return stbi__errpf("not HDR", "Corrupt HDR image"); 0014a e9 21 07 00 00 jmp $LN327@stbi__hdr_ $LN34@stbi__hdr_: ; 6756 : token += 3; 0014f 48 8b 4c 24 48 mov rcx, QWORD PTR token$[rsp] ; 6757 : height = (int)strtol(token, &token, 10); 00154 48 8d 54 24 48 lea rdx, QWORD PTR token$[rsp] 00159 48 03 cf add rcx, rdi 0015c 41 b8 0a 00 00 00 mov r8d, 10 00162 48 89 4c 24 48 mov QWORD PTR token$[rsp], rcx 00167 ff 15 00 00 00 00 call QWORD PTR __imp_strtol ; 6758 : while (*token == ' ') ++token; 0016d 48 8b 4c 24 48 mov rcx, QWORD PTR token$[rsp] 00172 8b f0 mov esi, eax 00174 89 44 24 3c mov DWORD PTR height$1$[rsp], eax 00178 80 39 20 cmp BYTE PTR [rcx], 32 ; 00000020H 0017b 75 10 jne SHORT $LN6@stbi__hdr_ 0017d 0f 1f 00 npad 3 $LL5@stbi__hdr_: 00180 48 ff c1 inc rcx 00183 48 89 4c 24 48 mov QWORD PTR token$[rsp], rcx 00188 80 39 20 cmp BYTE PTR [rcx], 32 ; 00000020H 0018b 74 f3 je SHORT $LL5@stbi__hdr_ $LN6@stbi__hdr_: ; 6759 : if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); 0018d 4c 8b c7 mov r8, rdi 00190 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_03FOKDFDHG@?$CLX?5@ 00197 ff 15 00 00 00 00 call QWORD PTR __imp_strncmp 0019d 85 c0 test eax, eax 0019f 0f 85 6c ff ff ff jne $LN332@stbi__hdr_ ; 6760 : token += 3; 001a5 48 8b 4c 24 48 mov rcx, QWORD PTR token$[rsp] ; 6761 : width = (int)strtol(token, NULL, 10); 001aa 44 8d 40 0a lea r8d, QWORD PTR [rax+10] 001ae 48 03 cf add rcx, rdi 001b1 33 d2 xor edx, edx 001b3 48 89 4c 24 48 mov QWORD PTR token$[rsp], rcx 001b8 ff 15 00 00 00 00 call QWORD PTR __imp_strtol 001be 89 44 24 30 mov DWORD PTR width$1$[rsp], eax ; 6762 : ; 6763 : if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); 001c2 81 fe 00 00 00 01 cmp esi, 16777216 ; 01000000H 001c8 7e 1f jle SHORT $LN36@stbi__hdr_ $LN333@stbi__hdr_: ; 6855 : } 001ca 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001d0 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001d9 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001dd 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ 001e4 e9 87 06 00 00 jmp $LN327@stbi__hdr_ $LN36@stbi__hdr_: ; 6764 : if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large", "Very large image (corrupt?)"); 001e9 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 001ee 7f da jg SHORT $LN333@stbi__hdr_ ; 6765 : ; 6766 : *x = width; 001f0 41 89 04 24 mov DWORD PTR [r12], eax ; 6767 : *y = height; 001f4 41 89 75 00 mov DWORD PTR [r13], esi ; 6768 : ; 6769 : if (comp) *comp = 3; 001f8 4d 85 f6 test r14, r14 001fb 74 03 je SHORT $LN38@stbi__hdr_ 001fd 41 89 3e mov DWORD PTR [r14], edi $LN38@stbi__hdr_: ; 467 : if (a < 0 || b < 0) return 0; 00200 45 85 ff test r15d, r15d 00203 44 8b e8 mov r13d, eax 00206 41 0f 45 ff cmovne edi, r15d 0020a 48 89 7c 24 40 mov QWORD PTR tv1792[rsp], rdi 0020f 85 c0 test eax, eax 00211 78 b7 js SHORT $LN333@stbi__hdr_ 00213 85 f6 test esi, esi 00215 78 b3 js SHORT $LN333@stbi__hdr_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00217 74 0d je SHORT $LN235@stbi__hdr_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00219 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0021e 99 cdq 0021f f7 fe idiv esi ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00221 44 3b e8 cmp r13d, eax 00224 7f a4 jg SHORT $LN333@stbi__hdr_ $LN235@stbi__hdr_: 00226 41 8b cd mov ecx, r13d 00229 0f af ce imul ecx, esi ; 467 : if (a < 0 || b < 0) return 0; 0022c 85 c9 test ecx, ecx 0022e 78 9a js SHORT $LN333@stbi__hdr_ 00230 85 ff test edi, edi 00232 78 96 js SHORT $LN333@stbi__hdr_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00234 74 0c je SHORT $LN234@stbi__hdr_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00236 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0023b 99 cdq 0023c f7 ff idiv edi ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0023e 3b c8 cmp ecx, eax 00240 7f 88 jg SHORT $LN333@stbi__hdr_ $LN234@stbi__hdr_: 00242 8b c7 mov eax, edi 00244 41 0f af c5 imul eax, r13d 00248 0f af c6 imul eax, esi ; 467 : if (a < 0 || b < 0) return 0; 0024b 85 c0 test eax, eax 0024d 0f 88 77 ff ff ff js $LN333@stbi__hdr_ ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00253 3d ff ff ff 1f cmp eax, 536870911 ; 1fffffffH 00258 0f 8f 6c ff ff ff jg $LN333@stbi__hdr_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0025e 85 f6 test esi, esi 00260 74 11 je SHORT $LN328@stbi__hdr_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00262 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00267 99 cdq 00268 f7 fe idiv esi ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0026a 44 3b e8 cmp r13d, eax 0026d 0f 8f 00 04 00 00 jg $LN225@stbi__hdr_ $LN328@stbi__hdr_: ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00273 41 8b cd mov ecx, r13d 00276 0f af ce imul ecx, esi 00279 85 ff test edi, edi 0027b 75 08 jne SHORT $LN115@stbi__hdr_ 0027d 41 8b c5 mov eax, r13d 00280 0f af c7 imul eax, edi 00283 eb 16 jmp SHORT $LN329@stbi__hdr_ $LN115@stbi__hdr_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00285 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0028a 99 cdq 0028b f7 ff idiv edi ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0028d 3b c8 cmp ecx, eax 0028f 0f 8f de 03 00 00 jg $LN225@stbi__hdr_ 00295 8b c7 mov eax, edi 00297 41 0f af c5 imul eax, r13d $LN329@stbi__hdr_: ; 516 : return stbi__malloc(a * b * c * d + add); 0029b 89 44 24 38 mov DWORD PTR tv1712[rsp], eax 0029f 0f af c6 imul eax, esi 002a2 c1 e0 02 shl eax, 2 002a5 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 002a8 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 002ae 48 89 44 24 28 mov QWORD PTR hdr_data$1$[rsp], rax 002b3 4c 8b e0 mov r12, rax ; 6770 : if (req_comp == 0) req_comp = 3; ; 6771 : ; 6772 : if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) ; 6773 : return stbi__errpf("too large", "HDR image is too large"); ; 6774 : ; 6775 : // Read data ; 6776 : hdr_data = (float*)stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); ; 6777 : if (!hdr_data) 002b6 48 85 c0 test rax, rax 002b9 0f 84 b4 03 00 00 je $LN225@stbi__hdr_ ; 6778 : return stbi__errpf("outofmem", "Out of memory"); ; 6779 : ; 6780 : // Load image data ; 6781 : // image data is stored as some number of sca ; 6782 : if (width < 8 || width >= 32768) { 002bf 41 8d 4d f8 lea ecx, DWORD PTR [r13-8] 002c3 81 f9 f7 7f 00 00 cmp ecx, 32759 ; 00007ff7H 002c9 0f 87 a4 04 00 00 ja $LN44@stbi__hdr_ ; 6790 : } ; 6791 : } ; 6792 : } ; 6793 : else { ; 6794 : // Read RLE-encoded data ; 6795 : scanline = NULL; 002cf 33 c0 xor eax, eax 002d1 48 89 44 24 20 mov QWORD PTR scanline$1$[rsp], rax ; 6796 : ; 6797 : for (j = 0; j < height; ++j) { 002d6 89 44 24 34 mov DWORD PTR j$1$[rsp], eax 002da 85 f6 test esi, esi 002dc 0f 8e 6f 05 00 00 jle $LN8@stbi__hdr_ 002e2 89 44 24 50 mov DWORD PTR tv1713[rsp], eax 002e6 66 66 0f 1f 84 00 00 00 00 00 npad 10 $LL15@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 002f0 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 002f7 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 002fe 73 10 jae SHORT $LN136@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00300 44 0f b6 38 movzx r15d, BYTE PTR [rax] 00304 48 ff c0 inc rax 00307 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0030e eb 28 jmp SHORT $LN330@stbi__hdr_ $LN136@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 00310 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00314 74 1f je SHORT $LN137@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00316 48 8b cb mov rcx, rbx 00319 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0031e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00325 44 0f b6 38 movzx r15d, BYTE PTR [rax] 00329 48 ff c0 inc rax 0032c 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00333 eb 03 jmp SHORT $LN330@stbi__hdr_ $LN137@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00335 45 32 ff xor r15b, r15b $LN330@stbi__hdr_: ; 6798 : c1 = stbi__get8(s); 00338 ba 30 00 00 00 mov edx, 48 ; 00000030H 0033d 48 8b cb mov rcx, rbx 00340 4c 8d 34 1a lea r14, QWORD PTR [rdx+rbx] ; 1077 : if (s->img_buffer < s->img_buffer_end) 00344 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0034b 73 0f jae SHORT $LN140@stbi__hdr_ ; 1078 : return *s->img_buffer++; 0034d 0f b6 30 movzx esi, BYTE PTR [rax] 00350 48 ff c0 inc rax 00353 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0035a eb 27 jmp SHORT $LN139@stbi__hdr_ $LN140@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 0035c 41 83 3e 00 cmp DWORD PTR [r14], 0 00360 74 1e je SHORT $LN141@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00362 48 8b cb mov rcx, rbx 00365 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0036a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00371 0f b6 30 movzx esi, BYTE PTR [rax] 00374 48 ff c0 inc rax 00377 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0037e eb 03 jmp SHORT $LN139@stbi__hdr_ $LN141@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00380 40 32 f6 xor sil, sil $LN139@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00383 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0038a 73 0f jae SHORT $LN132@stbi__hdr_ ; 1078 : return *s->img_buffer++; 0038c 0f b6 08 movzx ecx, BYTE PTR [rax] 0038f 48 ff c0 inc rax 00392 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00399 eb 26 jmp SHORT $LN131@stbi__hdr_ $LN132@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 0039b 41 83 3e 00 cmp DWORD PTR [r14], 0 0039f 74 1e je SHORT $LN133@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 003a1 48 8b cb mov rcx, rbx 003a4 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 003a9 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 003b0 0f b6 08 movzx ecx, BYTE PTR [rax] 003b3 48 ff c0 inc rax 003b6 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003bd eb 02 jmp SHORT $LN131@stbi__hdr_ $LN133@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 003bf 32 c9 xor cl, cl $LN131@stbi__hdr_: ; 6799 : c2 = stbi__get8(s); ; 6800 : len = stbi__get8(s); 003c1 0f b6 f9 movzx edi, cl ; 6801 : if (c1 != 2 || c2 != 2 || (len & 0x80)) { 003c4 41 80 ff 02 cmp r15b, 2 003c8 0f 85 2c 03 00 00 jne $LN46@stbi__hdr_ 003ce 41 3a f7 cmp sil, r15b 003d1 0f 85 23 03 00 00 jne $LN46@stbi__hdr_ 003d7 40 84 ff test dil, dil 003da 0f 88 1a 03 00 00 js $LN46@stbi__hdr_ ; 6814 : } ; 6815 : len <<= 8; 003e0 c1 e7 08 shl edi, 8 ; 1077 : if (s->img_buffer < s->img_buffer_end) 003e3 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 003ea 73 0f jae SHORT $LN162@stbi__hdr_ ; 1078 : return *s->img_buffer++; 003ec 0f b6 08 movzx ecx, BYTE PTR [rax] 003ef 48 ff c0 inc rax 003f2 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 003f9 eb 26 jmp SHORT $LN161@stbi__hdr_ $LN162@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 003fb 41 83 3e 00 cmp DWORD PTR [r14], 0 003ff 74 1e je SHORT $LN163@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00401 48 8b cb mov rcx, rbx 00404 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00409 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00410 0f b6 08 movzx ecx, BYTE PTR [rax] 00413 48 ff c0 inc rax 00416 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0041d eb 02 jmp SHORT $LN161@stbi__hdr_ $LN163@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 0041f 32 c9 xor cl, cl $LN161@stbi__hdr_: ; 6816 : len |= stbi__get8(s); 00421 0f b6 c1 movzx eax, cl 00424 0b c7 or eax, edi ; 6817 : if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } 00426 41 3b c5 cmp eax, r13d 00429 0f 85 98 02 00 00 jne $LN199@stbi__hdr_ ; 6818 : if (scanline == NULL) { 0042f 4c 8b 4c 24 20 mov r9, QWORD PTR scanline$1$[rsp] 00434 4d 85 c9 test r9, r9 00437 75 22 jne SHORT $LN49@stbi__hdr_ ; 502 : return stbi__malloc(a * b + add); 00439 42 8d 04 ad 00 00 00 00 lea eax, DWORD PTR [r13*4] 00441 48 63 c8 movsxd rcx, eax ; 438 : return STBI_MALLOC(size); 00444 ff 15 00 00 00 00 call QWORD PTR __imp_malloc 0044a 48 89 44 24 20 mov QWORD PTR scanline$1$[rsp], rax 0044f 4c 8b c8 mov r9, rax ; 6819 : scanline = (stbi_uc*)stbi__malloc_mad2(width, 4, 0); ; 6820 : if (!scanline) { 00452 48 85 c0 test rax, rax 00455 0f 84 0f 02 00 00 je $LN200@stbi__hdr_ $LN49@stbi__hdr_: ; 6822 : return stbi__errpf("outofmem", "Out of memory"); ; 6823 : } ; 6824 : } ; 6825 : ; 6826 : for (k = 0; k < 4; ++k) { 0045b 45 33 e4 xor r12d, r12d 0045e 66 90 npad 2 $LL18@stbi__hdr_: ; 6827 : int nleft; ; 6828 : i = 0; 00460 45 33 f6 xor r14d, r14d 00463 45 33 ff xor r15d, r15d ; 6829 : while ((nleft = width - i) > 0) { 00466 41 8b f5 mov esi, r13d 00469 45 85 ed test r13d, r13d 0046c 0f 8e 62 01 00 00 jle $LN16@stbi__hdr_ 00472 0f 1f 40 00 66 66 0f 1f 84 00 00 00 00 00 npad 14 $LL19@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00480 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00487 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0048e 72 19 jb SHORT $LN331@stbi__hdr_ ; 1079 : if (s->read_from_callbacks) { 00490 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00494 0f 84 f8 01 00 00 je $LN196@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 0049a 48 8b cb mov rcx, rbx 0049d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 004a2 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] $LN331@stbi__hdr_: ; 6830 : count = stbi__get8(s); ; 6831 : if (count > 128) { 004a9 0f b6 38 movzx edi, BYTE PTR [rax] 004ac 48 ff c0 inc rax 004af 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004b6 40 80 ff 80 cmp dil, 128 ; 00000080H 004ba 0f 86 84 00 00 00 jbe $LN50@stbi__hdr_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 004c0 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 004c7 73 0f jae SHORT $LN154@stbi__hdr_ ; 1078 : return *s->img_buffer++; 004c9 0f b6 10 movzx edx, BYTE PTR [rax] 004cc 48 ff c0 inc rax 004cf 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004d6 eb 26 jmp SHORT $LN153@stbi__hdr_ $LN154@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 004d8 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 004dc 74 1e je SHORT $LN155@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 004de 48 8b cb mov rcx, rbx 004e1 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 004e6 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 004ed 0f b6 10 movzx edx, BYTE PTR [rax] 004f0 48 ff c0 inc rax 004f3 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 004fa eb 02 jmp SHORT $LN153@stbi__hdr_ $LN155@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 004fc 32 d2 xor dl, dl $LN153@stbi__hdr_: ; 6832 : // Run ; 6833 : value = stbi__get8(s); ; 6834 : count -= 128; 004fe 40 80 c7 80 add dil, 128 ; 00000080H ; 6835 : if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } 00502 0f 84 8a 01 00 00 je $LN196@stbi__hdr_ 00508 44 0f b6 c7 movzx r8d, dil 0050c 44 3b c6 cmp r8d, esi 0050f 0f 87 7d 01 00 00 ja $LN196@stbi__hdr_ ; 6836 : for (z = 0; z < count; ++z) 00515 4c 8b 4c 24 20 mov r9, QWORD PTR scanline$1$[rsp] 0051a 40 84 ff test dil, dil 0051d 0f 84 a3 00 00 00 je $LN25@stbi__hdr_ 00523 4b 8d 04 bc lea rax, QWORD PTR [r12+r15*4] 00527 45 03 f0 add r14d, r8d 0052a 49 03 c1 add rax, r9 0052d 41 8b c8 mov ecx, r8d 00530 4d 03 f8 add r15, r8 $LL23@stbi__hdr_: ; 6837 : scanline[i++ * 4 + k] = value; 00533 88 10 mov BYTE PTR [rax], dl 00535 48 8d 40 04 lea rax, QWORD PTR [rax+4] 00539 48 83 e9 01 sub rcx, 1 0053d 75 f4 jne SHORT $LL23@stbi__hdr_ ; 6838 : } 0053f e9 82 00 00 00 jmp $LN25@stbi__hdr_ $LN50@stbi__hdr_: ; 6839 : else { ; 6840 : // Dump ; 6841 : if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } 00544 40 84 ff test dil, dil 00547 0f 84 45 01 00 00 je $LN196@stbi__hdr_ 0054d 40 0f b6 c7 movzx eax, dil 00551 3b c6 cmp eax, esi 00553 0f 87 39 01 00 00 ja $LN196@stbi__hdr_ ; 6842 : for (z = 0; z < count; ++z) 00559 40 84 ff test dil, dil 0055c 74 63 je SHORT $LN256@stbi__hdr_ 0055e 4b 8d 3c bc lea rdi, QWORD PTR [r12+r15*4] 00562 44 03 f0 add r14d, eax 00565 48 03 7c 24 20 add rdi, QWORD PTR scanline$1$[rsp] 0056a 8b f0 mov esi, eax 0056c 4c 03 f8 add r15, rax 0056f 90 npad 1 $LL26@stbi__hdr_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00570 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00577 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0057e 73 0f jae SHORT $LN150@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00580 0f b6 08 movzx ecx, BYTE PTR [rax] 00583 48 ff c0 inc rax 00586 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0058d eb 26 jmp SHORT $LN149@stbi__hdr_ $LN150@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 0058f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00593 74 1e je SHORT $LN151@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00595 48 8b cb mov rcx, rbx 00598 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0059d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 005a4 0f b6 08 movzx ecx, BYTE PTR [rax] 005a7 48 ff c0 inc rax 005aa 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 005b1 eb 02 jmp SHORT $LN149@stbi__hdr_ $LN151@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 005b3 32 c9 xor cl, cl $LN149@stbi__hdr_: ; 6843 : scanline[i++ * 4 + k] = stbi__get8(s); 005b5 88 0f mov BYTE PTR [rdi], cl 005b7 48 83 c7 04 add rdi, 4 005bb 48 83 ee 01 sub rsi, 1 005bf 75 af jne SHORT $LL26@stbi__hdr_ $LN256@stbi__hdr_: ; 6829 : while ((nleft = width - i) > 0) { 005c1 4c 8b 4c 24 20 mov r9, QWORD PTR scanline$1$[rsp] $LN25@stbi__hdr_: 005c6 41 8b f5 mov esi, r13d 005c9 41 2b f6 sub esi, r14d 005cc 85 f6 test esi, esi 005ce 0f 8f ac fe ff ff jg $LL19@stbi__hdr_ $LN16@stbi__hdr_: ; 6822 : return stbi__errpf("outofmem", "Out of memory"); ; 6823 : } ; 6824 : } ; 6825 : ; 6826 : for (k = 0; k < 4; ++k) { 005d4 49 ff c4 inc r12 005d7 49 83 fc 04 cmp r12, 4 005db 0f 8c 7f fe ff ff jl $LL18@stbi__hdr_ ; 6844 : } ; 6845 : } ; 6846 : } ; 6847 : for (i = 0; i < width; ++i) 005e1 4c 8b 64 24 28 mov r12, QWORD PTR hdr_data$1$[rsp] 005e6 45 85 ed test r13d, r13d 005e9 7e 45 jle SHORT $LN13@stbi__hdr_ 005eb 48 63 44 24 50 movsxd rax, DWORD PTR tv1713[rsp] 005f0 49 8b f9 mov rdi, r9 005f3 4c 63 7c 24 40 movsxd r15, DWORD PTR tv1792[rsp] 005f8 45 8b f5 mov r14d, r13d 005fb 4c 8b 6c 24 40 mov r13, QWORD PTR tv1792[rsp] 00600 49 8d 34 84 lea rsi, QWORD PTR [r12+rax*4] 00604 49 c1 e7 02 shl r15, 2 00608 0f 1f 84 00 00 00 00 00 npad 8 $LL29@stbi__hdr_: ; 6848 : stbi__hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); 00610 45 8b c5 mov r8d, r13d 00613 48 8b d7 mov rdx, rdi 00616 48 8b ce mov rcx, rsi 00619 e8 00 00 00 00 call stbi__hdr_convert 0061e 49 03 f7 add rsi, r15 00621 48 83 c7 04 add rdi, 4 00625 49 83 ee 01 sub r14, 1 00629 75 e5 jne SHORT $LL29@stbi__hdr_ 0062b 44 8b 6c 24 30 mov r13d, DWORD PTR width$1$[rsp] $LN13@stbi__hdr_: ; 6796 : ; 6797 : for (j = 0; j < height; ++j) { 00630 8b 4c 24 34 mov ecx, DWORD PTR j$1$[rsp] 00634 44 8b 74 24 38 mov r14d, DWORD PTR tv1712[rsp] 00639 ff c1 inc ecx 0063b 44 01 74 24 50 add DWORD PTR tv1713[rsp], r14d 00640 89 4c 24 34 mov DWORD PTR j$1$[rsp], ecx 00644 3b 4c 24 3c cmp ecx, DWORD PTR height$1$[rsp] 00648 0f 8c a2 fc ff ff jl $LL15@stbi__hdr_ ; 6849 : } ; 6850 : if (scanline) 0064e 48 8b 4c 24 20 mov rcx, QWORD PTR scanline$1$[rsp] 00653 48 85 c9 test rcx, rcx 00656 0f 84 f5 01 00 00 je $LN8@stbi__hdr_ ; 6851 : STBI_FREE(scanline); 0065c ff 15 00 00 00 00 call QWORD PTR __imp_free ; 6852 : } ; 6853 : ; 6854 : return hdr_data; 00662 49 8b c4 mov rax, r12 00665 e9 11 02 00 00 jmp $LN1@stbi__hdr_ $LN200@stbi__hdr_: ; 6821 : STBI_FREE(hdr_data); 0066a 49 8b cc mov rcx, r12 0066d ff 15 00 00 00 00 call QWORD PTR __imp_free $LN225@stbi__hdr_: ; 6855 : } 00673 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00679 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00682 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00686 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ 0068d e9 de 01 00 00 jmp $LN327@stbi__hdr_ $LN196@stbi__hdr_: 00692 48 8b 4c 24 28 mov rcx, QWORD PTR hdr_data$1$[rsp] 00697 ff 15 00 00 00 00 call QWORD PTR __imp_free 0069d 48 8b 4c 24 20 mov rcx, QWORD PTR scanline$1$[rsp] 006a2 ff 15 00 00 00 00 call QWORD PTR __imp_free 006a8 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 006ae 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006b7 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006bb 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07DPPMCAKL@corrupt@ 006c2 e9 a9 01 00 00 jmp $LN327@stbi__hdr_ $LN199@stbi__hdr_: ; 6817 : if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } 006c7 49 8b cc mov rcx, r12 006ca ff 15 00 00 00 00 call QWORD PTR __imp_free 006d0 48 8b 4c 24 20 mov rcx, QWORD PTR scanline$1$[rsp] 006d5 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 006db 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 006e1 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 006ea 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 006ee 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0CA@JBEOCDFN@invalid?5decoded?5scanline?5length@ ; 6817 : if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } 006f5 e9 76 01 00 00 jmp $LN327@stbi__hdr_ $LN46@stbi__hdr_: ; 6802 : // not run-length encoded, so we have to actually use THIS data as a decoded ; 6803 : // pixel (note this can't be a valid pixel--one of RGB must be >= 128) ; 6804 : stbi_uc rgbe[4]; ; 6805 : rgbe[0] = (stbi_uc)c1; 006fa 44 88 7c 24 50 mov BYTE PTR rgbe$17[rsp], r15b ; 6806 : rgbe[1] = (stbi_uc)c2; 006ff 40 88 74 24 51 mov BYTE PTR rgbe$17[rsp+1], sil ; 6807 : rgbe[2] = (stbi_uc)len; 00704 88 4c 24 52 mov BYTE PTR rgbe$17[rsp+2], cl ; 1077 : if (s->img_buffer < s->img_buffer_end) 00708 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0070f 73 0f jae SHORT $LN144@stbi__hdr_ ; 1078 : return *s->img_buffer++; 00711 0f b6 08 movzx ecx, BYTE PTR [rax] 00714 48 ff c0 inc rax 00717 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0071e eb 26 jmp SHORT $LN143@stbi__hdr_ $LN144@stbi__hdr_: ; 1079 : if (s->read_from_callbacks) { 00720 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00724 74 1e je SHORT $LN145@stbi__hdr_ ; 1080 : stbi__refill_buffer(s); 00726 48 8b cb mov rcx, rbx 00729 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0072e 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00735 0f b6 08 movzx ecx, BYTE PTR [rax] 00738 48 ff c0 inc rax 0073b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00742 eb 02 jmp SHORT $LN143@stbi__hdr_ $LN145@stbi__hdr_: ; 1082 : } ; 1083 : return 0; 00744 32 c9 xor cl, cl $LN143@stbi__hdr_: ; 6808 : rgbe[3] = (stbi_uc)stbi__get8(s); ; 6809 : stbi__hdr_convert(hdr_data, rgbe, req_comp); 00746 48 8b 7c 24 40 mov rdi, QWORD PTR tv1792[rsp] 0074b 48 8d 54 24 50 lea rdx, QWORD PTR rgbe$17[rsp] 00750 88 4c 24 53 mov BYTE PTR rgbe$17[rsp+3], cl 00754 44 8b c7 mov r8d, edi 00757 49 8b cc mov rcx, r12 0075a e8 00 00 00 00 call stbi__hdr_convert ; 6810 : i = 1; ; 6811 : j = 0; ; 6812 : STBI_FREE(scanline); 0075f 48 8b 4c 24 20 mov rcx, QWORD PTR scanline$1$[rsp] 00764 45 33 ff xor r15d, r15d 00767 ff 15 00 00 00 00 call QWORD PTR __imp_free ; 6813 : goto main_decode_loop; // yes, this makes no sense 0076d 45 8d 67 01 lea r12d, QWORD PTR [r15+1] 00771 eb 18 jmp SHORT $main_decode_loop$335 $LN44@stbi__hdr_: ; 6783 : // Read flat data ; 6784 : for (j = 0; j < height; ++j) { 00773 45 33 ff xor r15d, r15d $LN9@stbi__hdr_: 00776 44 3b fe cmp r15d, esi 00779 0f 8d cd 00 00 00 jge $LN254@stbi__hdr_ ; 6785 : for (i = 0; i < width; ++i) { 0077f 45 33 e4 xor r12d, r12d $LN12@stbi__hdr_: 00782 45 3b e5 cmp r12d, r13d 00785 0f 8d b5 00 00 00 jge $LN7@stbi__hdr_ $main_decode_loop$335: ; 1129 : if (s->io.read) { 0078b 4c 8b 73 10 mov r14, QWORD PTR [rbx+16] 0078f 4d 85 f6 test r14, r14 00792 74 55 je SHORT $LN228@stbi__hdr_ ; 1130 : int blen = (int)(s->img_buffer_end - s->img_buffer); 00794 8b b3 c8 00 00 00 mov esi, DWORD PTR [rbx+200] 0079a 2b b3 c0 00 00 00 sub esi, DWORD PTR [rbx+192] ; 1131 : if (blen < n) { 007a0 83 fe 04 cmp esi, 4 007a3 7d 44 jge SHORT $LN228@stbi__hdr_ ; 1132 : int res, count; ; 1133 : ; 1134 : memcpy(buffer, s->img_buffer, blen); 007a5 48 8b 93 c0 00 00 00 mov rdx, QWORD PTR [rbx+192] 007ac 48 8d 4c 24 50 lea rcx, QWORD PTR rgbe$18[rsp] 007b1 48 63 fe movsxd rdi, esi 007b4 4c 8b c7 mov r8, rdi 007b7 e8 00 00 00 00 call memcpy ; 1135 : ; 1136 : count = (s->io.read)(s->io_user_data, (char*)buffer + blen, n - blen); 007bc 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 007c0 48 8d 54 24 50 lea rdx, QWORD PTR rgbe$18[rsp] 007c5 41 b8 04 00 00 00 mov r8d, 4 007cb 48 03 d7 add rdx, rdi 007ce 44 2b c6 sub r8d, esi 007d1 41 ff d6 call r14 ; 1137 : res = (count == (n - blen)); ; 1138 : s->img_buffer = s->img_buffer_end; 007d4 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] ; 1139 : return res; 007db 48 8b 7c 24 40 mov rdi, QWORD PTR tv1792[rsp] 007e0 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 007e7 eb 21 jmp SHORT $LN65@stbi__hdr_ $LN228@stbi__hdr_: ; 1140 : } ; 1141 : } ; 1142 : ; 1143 : if (s->img_buffer + n <= s->img_buffer_end) { 007e9 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 007f0 48 8d 48 04 lea rcx, QWORD PTR [rax+4] 007f4 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 007fb 77 0d ja SHORT $LN65@stbi__hdr_ ; 1144 : memcpy(buffer, s->img_buffer, n); 007fd 8b 00 mov eax, DWORD PTR [rax] 007ff 89 44 24 50 mov DWORD PTR rgbe$18[rsp], eax ; 1145 : s->img_buffer += n; 00803 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx $LN65@stbi__hdr_: ; 6786 : stbi_uc rgbe[4]; ; 6787 : main_decode_loop: ; 6788 : stbi__getn(s, rgbe, 4); ; 6789 : stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); 0080a 8b c7 mov eax, edi 0080c 48 8d 54 24 50 lea rdx, QWORD PTR rgbe$18[rsp] 00811 41 0f af c7 imul eax, r15d 00815 44 8b c7 mov r8d, edi 00818 41 0f af c5 imul eax, r13d 0081c 48 63 c8 movsxd rcx, eax 0081f 8b c7 mov eax, edi 00821 41 0f af c4 imul eax, r12d 00825 48 98 cdqe 00827 48 03 c8 add rcx, rax 0082a 48 8b 44 24 28 mov rax, QWORD PTR hdr_data$1$[rsp] 0082f 48 8d 0c 88 lea rcx, QWORD PTR [rax+rcx*4] 00833 e8 00 00 00 00 call stbi__hdr_convert 00838 41 ff c4 inc r12d 0083b e9 42 ff ff ff jmp $LN12@stbi__hdr_ $LN7@stbi__hdr_: ; 6783 : // Read flat data ; 6784 : for (j = 0; j < height; ++j) { 00840 8b 74 24 3c mov esi, DWORD PTR height$1$[rsp] 00844 41 ff c7 inc r15d 00847 e9 2a ff ff ff jmp $LN9@stbi__hdr_ $LN254@stbi__hdr_: 0084c 4c 8b 64 24 28 mov r12, QWORD PTR hdr_data$1$[rsp] $LN8@stbi__hdr_: ; 6852 : } ; 6853 : ; 6854 : return hdr_data; 00851 49 8b c4 mov rax, r12 00854 eb 25 jmp SHORT $LN1@stbi__hdr_ $LN224@stbi__hdr_: ; 431 : stbi__g_failure_reason = str; 00856 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0085c 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00865 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00869 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BD@NKJFFLKL@unsupported?5format@ $LN327@stbi__hdr_: ; 6855 : } 00870 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 00875 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00879 33 c0 xor eax, eax $LN1@stbi__hdr_: 0087b 48 8b 8d 60 03 00 00 mov rcx, QWORD PTR __$ArrayPad$[rbp-256] 00882 48 33 cc xor rcx, rsp 00885 e8 00 00 00 00 call __security_check_cookie 0088a 48 81 c4 78 04 00 00 add rsp, 1144 ; 00000478H 00891 41 5f pop r15 00893 41 5e pop r14 00895 41 5d pop r13 00897 41 5c pop r12 00899 5f pop rdi 0089a 5e pop rsi 0089b 5b pop rbx 0089c 5d pop rbp 0089d c3 ret 0 stbi__hdr_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_test _TEXT SEGMENT s$ = 48 stbi__pnm_test PROC ; COMDAT ; 7063 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 57 push rdi 00006 48 83 ec 20 sub rsp, 32 ; 00000020H ; 1077 : if (s->img_buffer < s->img_buffer_end) 0000a 48 8b 81 c0 00 00 00 mov rax, QWORD PTR [rcx+192] ; 7063 : { 00011 48 8b d9 mov rbx, rcx ; 1077 : if (s->img_buffer < s->img_buffer_end) 00014 48 3b 81 c8 00 00 00 cmp rax, QWORD PTR [rcx+200] 0001b 73 0f jae SHORT $LN6@stbi__pnm_ ; 1078 : return *s->img_buffer++; 0001d 0f b6 38 movzx edi, BYTE PTR [rax] 00020 48 ff c0 inc rax 00023 48 89 81 c0 00 00 00 mov QWORD PTR [rcx+192], rax 0002a eb 24 jmp SHORT $LN22@stbi__pnm_ $LN6@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 0002c 83 79 30 00 cmp DWORD PTR [rcx+48], 0 00030 74 1b je SHORT $LN7@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 00032 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00037 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 0003e 0f b6 38 movzx edi, BYTE PTR [rax] 00041 48 ff c0 inc rax 00044 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0004b eb 03 jmp SHORT $LN22@stbi__pnm_ $LN7@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 0004d 40 32 ff xor dil, dil $LN22@stbi__pnm_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00050 b9 30 00 00 00 mov ecx, 48 ; 00000030H 00055 48 8b d3 mov rdx, rbx 00058 4c 8d 04 19 lea r8, QWORD PTR [rcx+rbx] 0005c 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 00063 73 0f jae SHORT $LN10@stbi__pnm_ ; 1078 : return *s->img_buffer++; 00065 0f b6 08 movzx ecx, BYTE PTR [rax] 00068 48 ff c0 inc rax 0006b 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00072 eb 26 jmp SHORT $LN9@stbi__pnm_ $LN10@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 00074 41 83 38 00 cmp DWORD PTR [r8], 0 00078 74 1e je SHORT $LN11@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 0007a 48 8b cb mov rcx, rbx 0007d e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00082 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00089 0f b6 08 movzx ecx, BYTE PTR [rax] 0008c 48 ff c0 inc rax 0008f 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 00096 eb 02 jmp SHORT $LN9@stbi__pnm_ $LN11@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 00098 32 c9 xor cl, cl $LN9@stbi__pnm_: ; 7064 : char p, t; ; 7065 : p = (char)stbi__get8(s); ; 7066 : t = (char)stbi__get8(s); ; 7067 : if (p != 'P' || (t != '5' && t != '6')) { 0009a 40 80 ff 50 cmp dil, 80 ; 00000050H 0009e 75 18 jne SHORT $LN3@stbi__pnm_ 000a0 80 e9 35 sub cl, 53 ; 00000035H 000a3 80 f9 01 cmp cl, 1 000a6 77 10 ja SHORT $LN3@stbi__pnm_ ; 7070 : } ; 7071 : return 1; 000a8 b8 01 00 00 00 mov eax, 1 ; 7072 : } 000ad 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000b2 48 83 c4 20 add rsp, 32 ; 00000020H 000b6 5f pop rdi 000b7 c3 ret 0 $LN3@stbi__pnm_: ; 342 : s->img_buffer = s->img_buffer_original; 000b8 48 8b 83 d0 00 00 00 mov rax, QWORD PTR [rbx+208] 000bf 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 000c6 48 8b 83 d8 00 00 00 mov rax, QWORD PTR [rbx+216] 000cd 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax ; 7068 : stbi__rewind(s); ; 7069 : return 0; 000d4 33 c0 xor eax, eax ; 7072 : } 000d6 48 8b 5c 24 30 mov rbx, QWORD PTR [rsp+48] 000db 48 83 c4 20 add rsp, 32 ; 00000020H 000df 5f pop rdi 000e0 c3 ret 0 stbi__pnm_test ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_load _TEXT SEGMENT s$ = 80 x$ = 88 y$ = 96 comp$ = 104 req_comp$ = 112 ri$ = 120 stbi__pnm_load PROC ; COMDAT ; 7075 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 30 sub rsp, 48 ; 00000030H 0001e 49 8b d9 mov rbx, r9 00021 4d 8b f8 mov r15, r8 00024 48 8b ea mov rbp, rdx ; 7076 : stbi_uc* out; ; 7077 : STBI_NOTUSED(ri); ; 7078 : ; 7079 : ri->bits_per_channel = stbi__pnm_info(s, (int*)&s->img_x, (int*)&s->img_y, (int*)&s->img_n); 00027 4c 8d 49 08 lea r9, QWORD PTR [rcx+8] 0002b 4c 8d 41 04 lea r8, QWORD PTR [rcx+4] 0002f 48 8b d1 mov rdx, rcx 00032 48 8b f9 mov rdi, rcx 00035 e8 00 00 00 00 call stbi__pnm_info 0003a 4c 8b 64 24 78 mov r12, QWORD PTR ri$[rsp] 0003f 8b c8 mov ecx, eax 00041 41 89 04 24 mov DWORD PTR [r12], eax ; 7080 : if (ri->bits_per_channel == 0) 00045 85 c0 test eax, eax 00047 0f 84 12 02 00 00 je $LN88@stbi__pnm_ ; 7081 : return 0; ; 7082 : ; 7083 : if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0004d 81 7f 04 00 00 00 01 cmp DWORD PTR [rdi+4], 16777216 ; 01000000H 00054 0f 87 e2 01 00 00 ja $LN78@stbi__pnm_ ; 7084 : if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large", "Very large image (corrupt?)"); 0005a 8b 07 mov eax, DWORD PTR [rdi] 0005c 3d 00 00 00 01 cmp eax, 16777216 ; 01000000H 00061 0f 87 d5 01 00 00 ja $LN78@stbi__pnm_ ; 7085 : ; 7086 : *x = s->img_x; 00067 89 45 00 mov DWORD PTR [rbp], eax ; 7087 : *y = s->img_y; 0006a 8b 47 04 mov eax, DWORD PTR [rdi+4] 0006d 41 89 07 mov DWORD PTR [r15], eax ; 7088 : if (comp) *comp = s->img_n; 00070 48 85 db test rbx, rbx 00073 74 05 je SHORT $LN5@stbi__pnm_ 00075 8b 47 08 mov eax, DWORD PTR [rdi+8] 00078 89 03 mov DWORD PTR [rbx], eax $LN5@stbi__pnm_: ; 7089 : ; 7090 : if (!stbi__mad4sizes_valid(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0)) 0007a 44 8b 47 08 mov r8d, DWORD PTR [rdi+8] 0007e 8b c1 mov eax, ecx 00080 44 8b 57 04 mov r10d, DWORD PTR [rdi+4] 00084 99 cdq 00085 44 8b 0f mov r9d, DWORD PTR [rdi] 00088 83 e2 07 and edx, 7 0008b 8d 0c 02 lea ecx, DWORD PTR [rdx+rax] 0008e c1 f9 03 sar ecx, 3 ; 467 : if (a < 0 || b < 0) return 0; 00091 45 85 c0 test r8d, r8d 00094 0f 88 a2 01 00 00 js $LN78@stbi__pnm_ 0009a 45 85 c9 test r9d, r9d 0009d 0f 88 99 01 00 00 js $LN78@stbi__pnm_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000a3 74 12 je SHORT $LN81@stbi__pnm_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000a5 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 000aa 99 cdq 000ab 41 f7 f9 idiv r9d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 000ae 44 3b c0 cmp r8d, eax 000b1 0f 8f 85 01 00 00 jg $LN78@stbi__pnm_ $LN81@stbi__pnm_: 000b7 45 8b d8 mov r11d, r8d 000ba 45 0f af d9 imul r11d, r9d ; 467 : if (a < 0 || b < 0) return 0; 000be 45 85 db test r11d, r11d 000c1 0f 88 75 01 00 00 js $LN78@stbi__pnm_ 000c7 45 85 d2 test r10d, r10d 000ca 0f 88 6c 01 00 00 js $LN78@stbi__pnm_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000d0 74 12 je SHORT $LN80@stbi__pnm_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000d2 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 000d7 99 cdq 000d8 41 f7 fa idiv r10d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 000db 44 3b d8 cmp r11d, eax 000de 0f 8f 58 01 00 00 jg $LN78@stbi__pnm_ $LN80@stbi__pnm_: 000e4 45 0f af da imul r11d, r10d ; 467 : if (a < 0 || b < 0) return 0; 000e8 45 85 db test r11d, r11d 000eb 0f 88 4b 01 00 00 js $LN78@stbi__pnm_ 000f1 85 c9 test ecx, ecx 000f3 0f 88 43 01 00 00 js $LN78@stbi__pnm_ ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 000f9 74 11 je SHORT $LN79@stbi__pnm_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 000fb b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00100 99 cdq 00101 f7 f9 idiv ecx ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00103 44 3b d8 cmp r11d, eax 00106 0f 8f 30 01 00 00 jg $LN78@stbi__pnm_ $LN79@stbi__pnm_: ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0010c 45 85 c9 test r9d, r9d 0010f 75 09 jne SHORT $LN52@stbi__pnm_ 00111 45 0f af c1 imul r8d, r9d 00115 45 8b d8 mov r11d, r8d 00118 eb 1c jmp SHORT $LN83@stbi__pnm_ $LN52@stbi__pnm_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 0011a b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 0011f 99 cdq 00120 41 f7 f9 idiv r9d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00123 44 3b c0 cmp r8d, eax 00126 0f 8f f4 00 00 00 jg $LN73@stbi__pnm_ 0012c 45 0f af c8 imul r9d, r8d 00130 45 8b c1 mov r8d, r9d 00133 45 8b d9 mov r11d, r9d $LN83@stbi__pnm_: ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 00136 45 85 d2 test r10d, r10d 00139 75 09 jne SHORT $LN57@stbi__pnm_ 0013b 45 8b ca mov r9d, r10d 0013e 45 0f af cb imul r9d, r11d 00142 eb 19 jmp SHORT $LN82@stbi__pnm_ $LN57@stbi__pnm_: ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00144 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00149 99 cdq 0014a 41 f7 fa idiv r10d ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 0014d 44 3b d8 cmp r11d, eax 00150 0f 8f ca 00 00 00 jg $LN73@stbi__pnm_ 00156 45 8b c8 mov r9d, r8d 00159 45 0f af ca imul r9d, r10d $LN82@stbi__pnm_: ; 468 : if (b == 0) return 1; // mul-by-0 is always safe 0015d 85 c9 test ecx, ecx 0015f 74 11 je SHORT $LN43@stbi__pnm_ ; 469 : // portable way to check for no overflows in a*b ; 470 : return a <= INT_MAX / b; 00161 b8 ff ff ff 7f mov eax, 2147483647 ; 7fffffffH 00166 99 cdq 00167 f7 f9 idiv ecx ; 492 : return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a * b, c) && 00169 44 3b c8 cmp r9d, eax 0016c 0f 8f ae 00 00 00 jg $LN73@stbi__pnm_ $LN43@stbi__pnm_: ; 516 : return stbi__malloc(a * b * c * d + add); 00172 41 0f af ca imul ecx, r10d 00176 41 0f af c8 imul ecx, r8d 0017a 48 63 c9 movsxd rcx, ecx ; 438 : return STBI_MALLOC(size); 0017d ff 15 00 00 00 00 call QWORD PTR __imp_malloc 00183 48 8b d8 mov rbx, rax ; 7091 : return stbi__errpuc("too large", "PNM too large"); ; 7092 : ; 7093 : out = (stbi_uc*)stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); ; 7094 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 00186 48 85 c0 test rax, rax 00189 0f 84 91 00 00 00 je $LN73@stbi__pnm_ ; 7095 : if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) { 0018f 41 8b 04 24 mov eax, DWORD PTR [r12] 00193 48 8b cf mov rcx, rdi 00196 99 cdq 00197 83 e2 07 and edx, 7 0019a 44 8d 04 02 lea r8d, DWORD PTR [rdx+rax] 0019e 48 8b d3 mov rdx, rbx 001a1 41 c1 f8 03 sar r8d, 3 001a5 44 0f af 47 08 imul r8d, DWORD PTR [rdi+8] 001aa 44 0f af 07 imul r8d, DWORD PTR [rdi] 001ae 44 0f af 47 04 imul r8d, DWORD PTR [rdi+4] 001b3 e8 00 00 00 00 call stbi__getn 001b8 85 c0 test eax, eax 001ba 75 25 jne SHORT $LN8@stbi__pnm_ ; 7096 : STBI_FREE(out); 001bc 48 8b cb mov rcx, rbx 001bf ff 15 00 00 00 00 call QWORD PTR __imp_free ; 431 : stbi__g_failure_reason = str; 001c5 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001cb 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001d4 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001d8 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_07IDKIDMGJ@bad?5PNM@ ; 7097 : return stbi__errpuc("bad PNM", "PNM file truncated"); 001df eb 75 jmp SHORT $LN115@stbi__pnm_ $LN8@stbi__pnm_: ; 7098 : } ; 7099 : ; 7100 : if (req_comp && req_comp != s->img_n) { 001e1 44 8b 44 24 70 mov r8d, DWORD PTR req_comp$[rsp] 001e6 45 85 c0 test r8d, r8d 001e9 74 30 je SHORT $LN12@stbi__pnm_ 001eb 8b 57 08 mov edx, DWORD PTR [rdi+8] 001ee 44 3b c2 cmp r8d, edx 001f1 74 28 je SHORT $LN12@stbi__pnm_ ; 7101 : if (ri->bits_per_channel == 16) { 001f3 41 83 3c 24 10 cmp DWORD PTR [r12], 16 001f8 48 8b cb mov rcx, rbx 001fb 8b 47 04 mov eax, DWORD PTR [rdi+4] 001fe 44 8b 0f mov r9d, DWORD PTR [rdi] 00201 89 44 24 20 mov DWORD PTR [rsp+32], eax 00205 75 07 jne SHORT $LN10@stbi__pnm_ ; 7102 : out = (stbi_uc*)stbi__convert_format16((stbi__uint16*)out, s->img_n, req_comp, s->img_x, s->img_y); 00207 e8 00 00 00 00 call stbi__convert_format16 ; 7103 : } 0020c eb 05 jmp SHORT $LN113@stbi__pnm_ $LN10@stbi__pnm_: ; 7104 : else { ; 7105 : out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); 0020e e8 00 00 00 00 call stbi__convert_format $LN113@stbi__pnm_: ; 7106 : } ; 7107 : if (out == NULL) return out; // stbi__convert_format frees input on failure 00213 48 8b d8 mov rbx, rax 00216 48 85 c0 test rax, rax 00219 74 44 je SHORT $LN88@stbi__pnm_ $LN12@stbi__pnm_: ; 7108 : } ; 7109 : return out; 0021b 48 8b c3 mov rax, rbx 0021e eb 41 jmp SHORT $LN1@stbi__pnm_ $LN73@stbi__pnm_: ; 431 : stbi__g_failure_reason = str; 00220 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00226 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0022f 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 00233 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_08NOGIMCHF@outofmem@ ; 7091 : return stbi__errpuc("too large", "PNM too large"); ; 7092 : ; 7093 : out = (stbi_uc*)stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0); ; 7094 : if (!out) return stbi__errpuc("outofmem", "Out of memory"); 0023a eb 1a jmp SHORT $LN115@stbi__pnm_ $LN78@stbi__pnm_: ; 7110 : } 0023c 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 00242 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 0024b 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0024f 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_09OJDLMMBJ@too?5large@ $LN115@stbi__pnm_: 00256 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0025b 48 89 14 01 mov QWORD PTR [rcx+rax], rdx $LN88@stbi__pnm_: 0025f 33 c0 xor eax, eax $LN1@stbi__pnm_: 00261 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] 00266 48 8b 6c 24 58 mov rbp, QWORD PTR [rsp+88] 0026b 48 8b 74 24 60 mov rsi, QWORD PTR [rsp+96] 00270 48 8b 7c 24 68 mov rdi, QWORD PTR [rsp+104] 00275 48 83 c4 30 add rsp, 48 ; 00000030H 00279 41 5f pop r15 0027b 41 5e pop r14 0027d 41 5c pop r12 0027f c3 ret 0 stbi__pnm_load ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_isspace _TEXT SEGMENT c$ = 8 stbi__pnm_isspace PROC ; COMDAT ; 7114 : return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; 00000 80 f9 20 cmp cl, 32 ; 00000020H 00003 74 0b je SHORT $LN3@stbi__pnm_ 00005 80 e9 09 sub cl, 9 00008 80 f9 04 cmp cl, 4 0000b 76 03 jbe SHORT $LN3@stbi__pnm_ 0000d 33 c0 xor eax, eax ; 7115 : } 0000f c3 ret 0 $LN3@stbi__pnm_: ; 7114 : return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; 00010 b8 01 00 00 00 mov eax, 1 ; 7115 : } 00015 c3 ret 0 stbi__pnm_isspace ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_skip_whitespace _TEXT SEGMENT s$ = 64 c$ = 72 stbi__pnm_skip_whitespace PROC ; COMDAT ; 7118 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 20 sub rsp, 32 ; 00000020H 0001e 4c 8b fa mov r15, rdx 00021 48 8d 71 20 lea rsi, QWORD PTR [rcx+32] 00025 48 8b d9 mov rbx, rcx 00028 0f 1f 84 00 00 00 00 00 npad 8 $LL2@stbi__pnm_: 00030 48 8d 6b 30 lea rbp, QWORD PTR [rbx+48] $LL5@stbi__pnm_: ; 1091 : if (s->io.read) { 00034 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00039 48 8d 7b 28 lea rdi, QWORD PTR [rbx+40] 0003d 74 13 je SHORT $LN53@stbi__pnm_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0003f 48 8b 0f mov rcx, QWORD PTR [rdi] 00042 ff 16 call QWORD PTR [rsi] 00044 85 c0 test eax, eax 00046 74 1a je SHORT $LN60@stbi__pnm_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00048 83 7d 00 00 cmp DWORD PTR [rbp], 0 0004c 0f 84 83 00 00 00 je $LN6@stbi__pnm_ $LN53@stbi__pnm_: ; 7119 : for (;;) { ; 7120 : while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) 00052 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 00059 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 00060 73 73 jae SHORT $LN6@stbi__pnm_ $LN60@stbi__pnm_: 00062 41 0f b6 07 movzx eax, BYTE PTR [r15] ; 7114 : return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; 00066 3c 20 cmp al, 32 ; 00000020H 00068 74 06 je SHORT $LN59@stbi__pnm_ 0006a 2c 09 sub al, 9 0006c 3c 04 cmp al, 4 0006e 77 5d ja SHORT $LN62@stbi__pnm_ $LN59@stbi__pnm_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 00070 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00077 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0007e 73 0f jae SHORT $LN22@stbi__pnm_ ; 1078 : return *s->img_buffer++; 00080 0f b6 08 movzx ecx, BYTE PTR [rax] 00083 48 ff c0 inc rax 00086 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0008d eb 26 jmp SHORT $LN81@stbi__pnm_ $LN22@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 0008f 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00093 74 1e je SHORT $LN23@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 00095 48 8b cb mov rcx, rbx 00098 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0009d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000a4 0f b6 08 movzx ecx, BYTE PTR [rax] 000a7 48 ff c0 inc rax 000aa 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000b1 eb 02 jmp SHORT $LN81@stbi__pnm_ $LN23@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 000b3 32 c9 xor cl, cl $LN81@stbi__pnm_: ; 7121 : *c = (char)stbi__get8(s); 000b5 ba 30 00 00 00 mov edx, 48 ; 00000030H 000ba 41 88 0f mov BYTE PTR [r15], cl 000bd 48 8b c3 mov rax, rbx 000c0 48 8d 73 20 lea rsi, QWORD PTR [rbx+32] 000c4 48 8d 2c 1a lea rbp, QWORD PTR [rdx+rbx] 000c8 e9 67 ff ff ff jmp $LL5@stbi__pnm_ $LN62@stbi__pnm_: 000cd 48 8d 73 20 lea rsi, QWORD PTR [rbx+32] 000d1 48 8d 7b 28 lea rdi, QWORD PTR [rbx+40] $LN6@stbi__pnm_: ; 1091 : if (s->io.read) { 000d5 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 000da 74 13 je SHORT $LN55@stbi__pnm_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 000dc 48 8b 0f mov rcx, QWORD PTR [rdi] 000df ff 16 call QWORD PTR [rsi] 000e1 85 c0 test eax, eax 000e3 74 1e je SHORT $LN58@stbi__pnm_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 000e5 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000e9 0f 84 d7 00 00 00 je $LN64@stbi__pnm_ $LN55@stbi__pnm_: ; 7122 : ; 7123 : if (stbi__at_eof(s) || *c != '#') 000ef 48 8b 83 c8 00 00 00 mov rax, QWORD PTR [rbx+200] 000f6 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 000fd 0f 83 c3 00 00 00 jae $LN64@stbi__pnm_ $LN58@stbi__pnm_: 00103 41 80 3f 23 cmp BYTE PTR [r15], 35 ; 00000023H 00107 0f 85 b9 00 00 00 jne $LN64@stbi__pnm_ 0010d 48 8d 6b 30 lea rbp, QWORD PTR [rbx+48] 00111 48 8d bb c8 00 00 00 lea rdi, QWORD PTR [rbx+200] 00118 0f 1f 84 00 00 00 00 00 npad 8 $LL7@stbi__pnm_: ; 1091 : if (s->io.read) { 00120 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00125 4c 8b f7 mov r14, rdi 00128 74 1f je SHORT $LN50@stbi__pnm_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0012a 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0012e 48 8d 73 20 lea rsi, QWORD PTR [rbx+32] 00132 ff 16 call QWORD PTR [rsi] 00134 85 c0 test eax, eax 00136 74 25 je SHORT $LN57@stbi__pnm_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00138 83 7d 00 00 cmp DWORD PTR [rbp], 0 0013c 0f 84 ee fe ff ff je $LL2@stbi__pnm_ 00142 48 8d bb c8 00 00 00 lea rdi, QWORD PTR [rbx+200] $LN50@stbi__pnm_: ; 7124 : break; ; 7125 : ; 7126 : while (!stbi__at_eof(s) && *c != '\n' && *c != '\r') 00149 49 8b 06 mov rax, QWORD PTR [r14] ; 1098 : return s->img_buffer >= s->img_buffer_end; 0014c 48 8d 73 20 lea rsi, QWORD PTR [rbx+32] ; 7124 : break; ; 7125 : ; 7126 : while (!stbi__at_eof(s) && *c != '\n' && *c != '\r') 00150 48 39 83 c0 00 00 00 cmp QWORD PTR [rbx+192], rax 00157 0f 83 d3 fe ff ff jae $LL2@stbi__pnm_ $LN57@stbi__pnm_: 0015d 41 0f b6 07 movzx eax, BYTE PTR [r15] 00161 3c 0a cmp al, 10 00163 0f 84 c7 fe ff ff je $LL2@stbi__pnm_ 00169 3c 0d cmp al, 13 0016b 0f 84 bf fe ff ff je $LL2@stbi__pnm_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 00171 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00178 48 3b 07 cmp rax, QWORD PTR [rdi] 0017b 73 0f jae SHORT $LN36@stbi__pnm_ ; 1078 : return *s->img_buffer++; 0017d 0f b6 08 movzx ecx, BYTE PTR [rax] 00180 48 ff c0 inc rax 00183 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0018a eb 26 jmp SHORT $LN82@stbi__pnm_ $LN36@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 0018c 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00190 74 1e je SHORT $LN37@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 00192 48 8b cb mov rcx, rbx 00195 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 0019a 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 001a1 0f b6 08 movzx ecx, BYTE PTR [rax] 001a4 48 ff c0 inc rax 001a7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 001ae eb 02 jmp SHORT $LN82@stbi__pnm_ $LN37@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 001b0 32 c9 xor cl, cl $LN82@stbi__pnm_: ; 7127 : *c = (char)stbi__get8(s); 001b2 ba 30 00 00 00 mov edx, 48 ; 00000030H 001b7 41 88 0f mov BYTE PTR [r15], cl 001ba 48 8b c3 mov rax, rbx 001bd 48 8d 2c 1a lea rbp, QWORD PTR [rdx+rbx] 001c1 e9 5a ff ff ff jmp $LL7@stbi__pnm_ $LN64@stbi__pnm_: ; 7128 : } ; 7129 : } 001c6 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 001cb 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 001d0 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 001d5 48 8b 7c 24 58 mov rdi, QWORD PTR [rsp+88] 001da 48 83 c4 20 add rsp, 32 ; 00000020H 001de 41 5f pop r15 001e0 41 5e pop r14 001e2 41 5c pop r12 001e4 c3 ret 0 stbi__pnm_skip_whitespace ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_isdigit _TEXT SEGMENT c$ = 8 stbi__pnm_isdigit PROC ; COMDAT ; 7133 : return c >= '0' && c <= '9'; 00000 33 c0 xor eax, eax 00002 80 e9 30 sub cl, 48 ; 00000030H 00005 80 f9 09 cmp cl, 9 00008 0f 96 c0 setbe al ; 7134 : } 0000b c3 ret 0 stbi__pnm_isdigit ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_getinteger _TEXT SEGMENT s$ = 64 c$ = 72 stbi__pnm_getinteger PROC ; COMDAT ; 7137 : { 00000 48 89 5c 24 08 mov QWORD PTR [rsp+8], rbx 00005 48 89 6c 24 10 mov QWORD PTR [rsp+16], rbp 0000a 48 89 74 24 18 mov QWORD PTR [rsp+24], rsi 0000f 48 89 7c 24 20 mov QWORD PTR [rsp+32], rdi 00014 41 54 push r12 00016 41 56 push r14 00018 41 57 push r15 0001a 48 83 ec 20 sub rsp, 32 ; 00000020H 0001e 4c 8b e2 mov r12, rdx ; 7138 : int value = 0; 00021 4c 8d b1 c8 00 00 00 lea r14, QWORD PTR [rcx+200] 00028 48 8b d9 mov rbx, rcx 0002b 48 8d a9 c0 00 00 00 lea rbp, QWORD PTR [rcx+192] 00032 33 ff xor edi, edi $LL2@stbi__pnm_: ; 1091 : if (s->io.read) { 00034 48 83 7b 10 00 cmp QWORD PTR [rbx+16], 0 00039 74 23 je SHORT $LN27@stbi__pnm_ ; 1092 : if (!(s->io.eof)(s->io_user_data)) return 0; 0003b 48 8b 4b 28 mov rcx, QWORD PTR [rbx+40] 0003f ff 53 20 call QWORD PTR [rbx+32] 00042 85 c0 test eax, eax 00044 74 25 je SHORT $LN29@stbi__pnm_ ; 1093 : // if feof() is true, check if buffer = end ; 1094 : // special case: we've only got the special 0 character at the end ; 1095 : if (s->read_from_callbacks == 0) return 1; 00046 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 0004a 4c 8d b3 c8 00 00 00 lea r14, QWORD PTR [rbx+200] 00051 48 8d ab c0 00 00 00 lea rbp, QWORD PTR [rbx+192] 00058 0f 84 bb 00 00 00 je $LN3@stbi__pnm_ $LN27@stbi__pnm_: ; 7139 : ; 7140 : while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { 0005e 49 8b 06 mov rax, QWORD PTR [r14] 00061 48 39 45 00 cmp QWORD PTR [rbp], rax 00065 0f 83 ae 00 00 00 jae $LN3@stbi__pnm_ $LN29@stbi__pnm_: 0006b 41 0f be 14 24 movsx edx, BYTE PTR [r12] ; 7133 : return c >= '0' && c <= '9'; 00070 8d 42 d0 lea eax, DWORD PTR [rdx-48] 00073 3c 09 cmp al, 9 00075 0f 87 9e 00 00 00 ja $LN3@stbi__pnm_ ; 1077 : if (s->img_buffer < s->img_buffer_end) 0007b 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] ; 7141 : value = value * 10 + (*c - '0'); 00082 8d 3c bf lea edi, DWORD PTR [rdi+rdi*4] 00085 8d 7f e8 lea edi, DWORD PTR [rdi-24] 00088 8d 3c 7a lea edi, DWORD PTR [rdx+rdi*2] ; 1077 : if (s->img_buffer < s->img_buffer_end) 0008b 4c 8d b3 c8 00 00 00 lea r14, QWORD PTR [rbx+200] 00092 48 8d ab c0 00 00 00 lea rbp, QWORD PTR [rbx+192] 00099 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 000a0 73 0f jae SHORT $LN17@stbi__pnm_ ; 1078 : return *s->img_buffer++; 000a2 0f b6 08 movzx ecx, BYTE PTR [rax] 000a5 48 ff c0 inc rax 000a8 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000af eb 26 jmp SHORT $LN16@stbi__pnm_ $LN17@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 000b1 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 000b5 74 1e je SHORT $LN18@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 000b7 48 8b cb mov rcx, rbx 000ba e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000bf 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000c6 0f b6 08 movzx ecx, BYTE PTR [rax] 000c9 48 ff c0 inc rax 000cc 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000d3 eb 02 jmp SHORT $LN16@stbi__pnm_ $LN18@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 000d5 32 c9 xor cl, cl $LN16@stbi__pnm_: ; 7142 : *c = (char)stbi__get8(s); 000d7 41 88 0c 24 mov BYTE PTR [r12], cl ; 7143 : if ((value > 214748364) || (value == 214748364 && *c > '7')) 000db 81 ff cc cc cc 0c cmp edi, 214748364 ; 0cccccccH 000e1 7f 0f jg SHORT $LN23@stbi__pnm_ 000e3 0f 85 4b ff ff ff jne $LL2@stbi__pnm_ 000e9 80 f9 37 cmp cl, 55 ; 00000037H 000ec 0f 8e 42 ff ff ff jle $LL2@stbi__pnm_ $LN23@stbi__pnm_: ; 431 : stbi__g_failure_reason = str; 000f2 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 000fb 8b 0d 00 00 00 00 mov ecx, DWORD PTR _tls_index 00101 ba 00 00 00 00 mov edx, OFFSET FLAT:stbi__g_failure_reason 00106 48 8b 0c c8 mov rcx, QWORD PTR [rax+rcx*8] 0010a 48 8d 05 00 00 00 00 lea rax, OFFSET FLAT:??_C@_0BH@OBINMOBC@integer?5parse?5overflow@ 00111 48 89 04 0a mov QWORD PTR [rdx+rcx], rax ; 7144 : return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int"); 00115 33 c0 xor eax, eax 00117 eb 02 jmp SHORT $LN1@stbi__pnm_ $LN3@stbi__pnm_: ; 7145 : } ; 7146 : ; 7147 : return value; 00119 8b c7 mov eax, edi $LN1@stbi__pnm_: ; 7148 : } 0011b 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] 00120 48 8b 6c 24 48 mov rbp, QWORD PTR [rsp+72] 00125 48 8b 74 24 50 mov rsi, QWORD PTR [rsp+80] 0012a 48 8b 7c 24 58 mov rdi, QWORD PTR [rsp+88] 0012f 48 83 c4 20 add rsp, 32 ; 00000020H 00133 41 5f pop r15 00135 41 5e pop r14 00137 41 5c pop r12 00139 c3 ret 0 stbi__pnm_getinteger ENDP _TEXT ENDS ; Function compile flags: /Ogtpy ; File D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\源代码\StgSharpC\stb_image.c ; COMDAT stbi__pnm_info _TEXT SEGMENT c$ = 32 dummy$ = 36 __$ArrayPad$ = 40 s$ = 112 x$ = 120 y$ = 128 comp$ = 136 stbi__pnm_info PROC ; COMDAT ; 7151 : { 00000 40 53 push rbx 00002 55 push rbp 00003 56 push rsi 00004 57 push rdi 00005 41 56 push r14 00007 41 57 push r15 00009 48 83 ec 38 sub rsp, 56 ; 00000038H 0000d 48 8b 05 00 00 00 00 mov rax, QWORD PTR __security_cookie 00014 48 33 c4 xor rax, rsp 00017 48 89 44 24 28 mov QWORD PTR __$ArrayPad$[rsp], rax ; 7152 : int maxv, dummy; ; 7153 : char c, p, t; ; 7154 : ; 7155 : if (!x) x = &dummy; ; 7156 : if (!y) y = &dummy; 0001c 48 85 d2 test rdx, rdx 0001f 48 8d 6c 24 24 lea rbp, QWORD PTR dummy$[rsp] 00024 48 8b d9 mov rbx, rcx ; 7157 : if (!comp) comp = &dummy; 00027 4c 8d 7c 24 24 lea r15, QWORD PTR dummy$[rsp] ; 342 : s->img_buffer = s->img_buffer_original; 0002c 48 8b 89 d0 00 00 00 mov rcx, QWORD PTR [rcx+208] 00033 4c 8d 74 24 24 lea r14, QWORD PTR dummy$[rsp] ; 7152 : int maxv, dummy; ; 7153 : char c, p, t; ; 7154 : ; 7155 : if (!x) x = &dummy; ; 7156 : if (!y) y = &dummy; 00038 48 0f 45 ea cmovne rbp, rdx ; 7157 : if (!comp) comp = &dummy; 0003c 4d 85 c0 test r8, r8 ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0003f 48 8b 83 d8 00 00 00 mov rax, QWORD PTR [rbx+216] ; 7157 : if (!comp) comp = &dummy; 00046 4d 0f 45 f8 cmovne r15, r8 ; 342 : s->img_buffer = s->img_buffer_original; 0004a 4d 85 c9 test r9, r9 0004d 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx ; 343 : s->img_buffer_end = s->img_buffer_original_end; 00054 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax 0005b 4d 0f 45 f1 cmovne r14, r9 ; 1077 : if (s->img_buffer < s->img_buffer_end) 0005f 48 3b c8 cmp rcx, rax 00062 73 0f jae SHORT $LN17@stbi__pnm_ ; 1078 : return *s->img_buffer++; 00064 0f b6 39 movzx edi, BYTE PTR [rcx] 00067 48 ff c1 inc rcx 0006a 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00071 eb 28 jmp SHORT $LN48@stbi__pnm_ $LN17@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 00073 83 7b 30 00 cmp DWORD PTR [rbx+48], 0 00077 74 1f je SHORT $LN18@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 00079 48 8b cb mov rcx, rbx 0007c e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00081 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00088 0f b6 38 movzx edi, BYTE PTR [rax] 0008b 48 8d 48 01 lea rcx, QWORD PTR [rax+1] 0008f 48 89 8b c0 00 00 00 mov QWORD PTR [rbx+192], rcx 00096 eb 03 jmp SHORT $LN48@stbi__pnm_ $LN18@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 00098 40 32 ff xor dil, dil $LN48@stbi__pnm_: ; 1077 : if (s->img_buffer < s->img_buffer_end) 0009b b8 30 00 00 00 mov eax, 48 ; 00000030H 000a0 48 8b d3 mov rdx, rbx 000a3 48 8d 34 03 lea rsi, QWORD PTR [rbx+rax] 000a7 48 3b 8b c8 00 00 00 cmp rcx, QWORD PTR [rbx+200] 000ae 73 10 jae SHORT $LN21@stbi__pnm_ ; 1078 : return *s->img_buffer++; 000b0 0f b6 11 movzx edx, BYTE PTR [rcx] 000b3 48 8d 41 01 lea rax, QWORD PTR [rcx+1] 000b7 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000be eb 25 jmp SHORT $LN20@stbi__pnm_ $LN21@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 000c0 83 3e 00 cmp DWORD PTR [rsi], 0 000c3 74 1e je SHORT $LN22@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 000c5 48 8b cb mov rcx, rbx 000c8 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 000cd 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 000d4 0f b6 10 movzx edx, BYTE PTR [rax] 000d7 48 ff c0 inc rax 000da 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 000e1 eb 02 jmp SHORT $LN20@stbi__pnm_ $LN22@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 000e3 32 d2 xor dl, dl $LN20@stbi__pnm_: ; 7158 : ; 7159 : stbi__rewind(s); ; 7160 : ; 7161 : // Get identifier ; 7162 : p = (char)stbi__get8(s); ; 7163 : t = (char)stbi__get8(s); ; 7164 : if (p != 'P' || (t != '5' && t != '6')) { 000e5 40 80 ff 50 cmp dil, 80 ; 00000050H 000e9 0f 85 2d 01 00 00 jne $LN6@stbi__pnm_ 000ef 8d 42 cb lea eax, DWORD PTR [rdx-53] 000f2 3c 01 cmp al, 1 000f4 0f 87 22 01 00 00 ja $LN6@stbi__pnm_ ; 7165 : stbi__rewind(s); ; 7166 : return 0; ; 7167 : } ; 7168 : ; 7169 : *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm 000fa 80 fa 36 cmp dl, 54 ; 00000036H 000fd b8 01 00 00 00 mov eax, 1 00102 b9 03 00 00 00 mov ecx, 3 00107 0f 44 c1 cmove eax, ecx 0010a 41 89 06 mov DWORD PTR [r14], eax ; 1077 : if (s->img_buffer < s->img_buffer_end) 0010d 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00114 48 3b 83 c8 00 00 00 cmp rax, QWORD PTR [rbx+200] 0011b 73 0f jae SHORT $LN27@stbi__pnm_ ; 1078 : return *s->img_buffer++; 0011d 0f b6 08 movzx ecx, BYTE PTR [rax] 00120 48 ff c0 inc rax 00123 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0012a eb 25 jmp SHORT $LN26@stbi__pnm_ $LN27@stbi__pnm_: ; 1079 : if (s->read_from_callbacks) { 0012c 83 3e 00 cmp DWORD PTR [rsi], 0 0012f 74 1e je SHORT $LN28@stbi__pnm_ ; 1080 : stbi__refill_buffer(s); 00131 48 8b cb mov rcx, rbx 00134 e8 00 00 00 00 call stbi__refill_buffer ; 1081 : return *s->img_buffer++; 00139 48 8b 83 c0 00 00 00 mov rax, QWORD PTR [rbx+192] 00140 0f b6 08 movzx ecx, BYTE PTR [rax] 00143 48 ff c0 inc rax 00146 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax 0014d eb 02 jmp SHORT $LN26@stbi__pnm_ $LN28@stbi__pnm_: ; 1082 : } ; 1083 : return 0; 0014f 32 c9 xor cl, cl $LN26@stbi__pnm_: ; 7170 : ; 7171 : c = (char)stbi__get8(s); 00151 88 4c 24 20 mov BYTE PTR c$[rsp], cl ; 7172 : stbi__pnm_skip_whitespace(s, &c); 00155 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 0015a 48 8b cb mov rcx, rbx 0015d e8 00 00 00 00 call stbi__pnm_skip_whitespace ; 7173 : ; 7174 : *x = stbi__pnm_getinteger(s, &c); // read width 00162 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 00167 48 8b cb mov rcx, rbx 0016a e8 00 00 00 00 call stbi__pnm_getinteger 0016f 89 45 00 mov DWORD PTR [rbp], eax ; 7175 : if (*x == 0) 00172 85 c0 test eax, eax 00174 75 28 jne SHORT $LN7@stbi__pnm_ $LN50@stbi__pnm_: ; 7188 : return 16; ; 7189 : else ; 7190 : return 8; ; 7191 : } 00176 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 0017c 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 00185 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 0018a 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 0018e 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0O@MKGNGALN@invalid?5width@ 00195 48 89 14 01 mov QWORD PTR [rcx+rax], rdx 00199 e9 9a 00 00 00 jmp $LN49@stbi__pnm_ $LN7@stbi__pnm_: ; 7176 : return stbi__err("invalid width", "PPM image header had zero or overflowing width"); ; 7177 : stbi__pnm_skip_whitespace(s, &c); 0019e 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 001a3 48 8b cb mov rcx, rbx 001a6 e8 00 00 00 00 call stbi__pnm_skip_whitespace ; 7178 : ; 7179 : *y = stbi__pnm_getinteger(s, &c); // read height 001ab 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 001b0 48 8b cb mov rcx, rbx 001b3 e8 00 00 00 00 call stbi__pnm_getinteger 001b8 41 89 07 mov DWORD PTR [r15], eax ; 7180 : if (*y == 0) 001bb 85 c0 test eax, eax 001bd 74 b7 je SHORT $LN50@stbi__pnm_ ; 7181 : return stbi__err("invalid width", "PPM image header had zero or overflowing width"); ; 7182 : stbi__pnm_skip_whitespace(s, &c); 001bf 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 001c4 48 8b cb mov rcx, rbx 001c7 e8 00 00 00 00 call stbi__pnm_skip_whitespace ; 7183 : ; 7184 : maxv = stbi__pnm_getinteger(s, &c); // read max value 001cc 48 8d 54 24 20 lea rdx, QWORD PTR c$[rsp] 001d1 48 8b cb mov rcx, rbx 001d4 e8 00 00 00 00 call stbi__pnm_getinteger 001d9 8b c8 mov ecx, eax ; 7185 : if (maxv > 65535) 001db 3d ff ff 00 00 cmp eax, 65535 ; 0000ffffH 001e0 7e 25 jle SHORT $LN9@stbi__pnm_ ; 431 : stbi__g_failure_reason = str; 001e2 8b 15 00 00 00 00 mov edx, DWORD PTR _tls_index 001e8 65 48 8b 04 25 58 00 00 00 mov rax, QWORD PTR gs:88 001f1 b9 00 00 00 00 mov ecx, OFFSET FLAT:stbi__g_failure_reason 001f6 48 8b 04 d0 mov rax, QWORD PTR [rax+rdx*8] 001fa 48 8d 15 00 00 00 00 lea rdx, OFFSET FLAT:??_C@_0BC@CNFMOKHC@max?5value?5?$DO?565535@ 00201 48 89 14 01 mov QWORD PTR [rcx+rax], rdx ; 7186 : return stbi__err("max value > 65535", "PPM image supports only 8-bit and 16-bit images"); 00205 eb 31 jmp SHORT $LN49@stbi__pnm_ $LN9@stbi__pnm_: ; 7187 : else if (maxv > 255) 00207 81 f9 ff 00 00 00 cmp ecx, 255 ; 000000ffH 0020d b8 08 00 00 00 mov eax, 8 00212 ba 10 00 00 00 mov edx, 16 00217 0f 4f c2 cmovg eax, edx 0021a eb 1e jmp SHORT $LN12@stbi__pnm_ $LN6@stbi__pnm_: ; 342 : s->img_buffer = s->img_buffer_original; 0021c 48 8b 83 d0 00 00 00 mov rax, QWORD PTR [rbx+208] 00223 48 89 83 c0 00 00 00 mov QWORD PTR [rbx+192], rax ; 343 : s->img_buffer_end = s->img_buffer_original_end; 0022a 48 8b 83 d8 00 00 00 mov rax, QWORD PTR [rbx+216] 00231 48 89 83 c8 00 00 00 mov QWORD PTR [rbx+200], rax $LN49@stbi__pnm_: ; 7188 : return 16; ; 7189 : else ; 7190 : return 8; ; 7191 : } 00238 33 c0 xor eax, eax $LN12@stbi__pnm_: 0023a 48 8b 4c 24 28 mov rcx, QWORD PTR __$ArrayPad$[rsp] 0023f 48 33 cc xor rcx, rsp 00242 e8 00 00 00 00 call __security_check_cookie 00247 48 83 c4 38 add rsp, 56 ; 00000038H 0024b 41 5f pop r15 0024d 41 5e pop r14 0024f 5f pop rdi 00250 5e pop rsi 00251 5d pop rbp 00252 5b pop rbx 00253 c3 ret 0 stbi__pnm_info ENDP _TEXT ENDS END