diff --git a/�代�/.vs/ProjectEvaluation/stgsharpdevelop.metadata.v7.bin b/�代�/.vs/ProjectEvaluation/stgsharpdevelop.metadata.v7.bin index c782e769..3e1ce2f7 100644 Binary files a/�代�/.vs/ProjectEvaluation/stgsharpdevelop.metadata.v7.bin and b/�代�/.vs/ProjectEvaluation/stgsharpdevelop.metadata.v7.bin differ diff --git a/�代�/.vs/ProjectEvaluation/stgsharpdevelop.projects.v7.bin b/�代�/.vs/ProjectEvaluation/stgsharpdevelop.projects.v7.bin index fb8f0c83..e20d425b 100644 Binary files a/�代�/.vs/ProjectEvaluation/stgsharpdevelop.projects.v7.bin and b/�代�/.vs/ProjectEvaluation/stgsharpdevelop.projects.v7.bin differ diff --git a/�代�/.vs/StgSharpDevelop/DesignTimeBuild/.dtbcache.v2 b/�代�/.vs/StgSharpDevelop/DesignTimeBuild/.dtbcache.v2 index 931eacb1..9d42fdc6 100644 Binary files a/�代�/.vs/StgSharpDevelop/DesignTimeBuild/.dtbcache.v2 and b/�代�/.vs/StgSharpDevelop/DesignTimeBuild/.dtbcache.v2 differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/2eda316c-117b-458c-ad89-cce182c68614.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/2eda316c-117b-458c-ad89-cce182c68614.vsidx deleted file mode 100644 index 282cb029..00000000 Binary files a/�代�/.vs/StgSharpDevelop/FileContentIndex/2eda316c-117b-458c-ad89-cce182c68614.vsidx and /dev/null differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/2fff2e6b-d610-4c1d-bdc7-e363f115952c.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/2fff2e6b-d610-4c1d-bdc7-e363f115952c.vsidx deleted file mode 100644 index c6f471da..00000000 Binary files a/�代�/.vs/StgSharpDevelop/FileContentIndex/2fff2e6b-d610-4c1d-bdc7-e363f115952c.vsidx and /dev/null differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/331f4577-f2db-49d3-82ce-156a7e0e6f9a.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/331f4577-f2db-49d3-82ce-156a7e0e6f9a.vsidx new file mode 100644 index 00000000..b7a30450 Binary files /dev/null and b/�代�/.vs/StgSharpDevelop/FileContentIndex/331f4577-f2db-49d3-82ce-156a7e0e6f9a.vsidx differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/61b841a9-3c48-424f-8b01-7cc51a802703.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/61b841a9-3c48-424f-8b01-7cc51a802703.vsidx new file mode 100644 index 00000000..21b99cc7 Binary files /dev/null and b/�代�/.vs/StgSharpDevelop/FileContentIndex/61b841a9-3c48-424f-8b01-7cc51a802703.vsidx differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/6a862799-b798-42ba-8669-3f4ab2e56f73.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/6a862799-b798-42ba-8669-3f4ab2e56f73.vsidx new file mode 100644 index 00000000..e23109b6 Binary files /dev/null and b/�代�/.vs/StgSharpDevelop/FileContentIndex/6a862799-b798-42ba-8669-3f4ab2e56f73.vsidx differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/8ab28b40-9cb9-4835-a588-666abc422265.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/8ab28b40-9cb9-4835-a588-666abc422265.vsidx new file mode 100644 index 00000000..6058fe84 Binary files /dev/null and b/�代�/.vs/StgSharpDevelop/FileContentIndex/8ab28b40-9cb9-4835-a588-666abc422265.vsidx differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/efd3058e-096b-46a1-a77c-d099dfbdc382.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/efd3058e-096b-46a1-a77c-d099dfbdc382.vsidx deleted file mode 100644 index ba6dc716..00000000 Binary files a/�代�/.vs/StgSharpDevelop/FileContentIndex/efd3058e-096b-46a1-a77c-d099dfbdc382.vsidx and /dev/null differ diff --git a/�代�/.vs/StgSharpDevelop/FileContentIndex/fc425983-c447-4530-bd0e-d878aeb682fb.vsidx b/�代�/.vs/StgSharpDevelop/FileContentIndex/fc425983-c447-4530-bd0e-d878aeb682fb.vsidx deleted file mode 100644 index 3b314873..00000000 Binary files a/�代�/.vs/StgSharpDevelop/FileContentIndex/fc425983-c447-4530-bd0e-d878aeb682fb.vsidx and /dev/null differ diff --git a/�代�/.vs/StgSharpDevelop/v17/.futdcache.v2 b/�代�/.vs/StgSharpDevelop/v17/.futdcache.v2 index b19749a7..58699020 100644 Binary files a/�代�/.vs/StgSharpDevelop/v17/.futdcache.v2 and b/�代�/.vs/StgSharpDevelop/v17/.futdcache.v2 differ diff --git a/�代�/.vs/StgSharpDevelop/v17/.suo b/�代�/.vs/StgSharpDevelop/v17/.suo index bbdd21d4..eb126838 100644 Binary files a/�代�/.vs/StgSharpDevelop/v17/.suo and b/�代�/.vs/StgSharpDevelop/v17/.suo differ diff --git a/�代�/.vs/StgSharpDevelop/v17/Browse.VC.db b/�代�/.vs/StgSharpDevelop/v17/Browse.VC.db index 2e559cbc..fea14287 100644 Binary files a/�代�/.vs/StgSharpDevelop/v17/Browse.VC.db and b/�代�/.vs/StgSharpDevelop/v17/Browse.VC.db differ diff --git a/�代�/.vs/StgSharpDevelop/v17/DocumentLayout.json b/�代�/.vs/StgSharpDevelop/v17/DocumentLayout.json index 2f63c2b5..fa6f7ee2 100644 --- a/�代�/.vs/StgSharpDevelop/v17/DocumentLayout.json +++ b/�代�/.vs/StgSharpDevelop/v17/DocumentLayout.json @@ -3,24 +3,104 @@ "WorkspaceRootPath": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\glpack.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\glpack.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\buffer\\fbo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\buffer\\fbo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\buffer\\ebo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\buffer\\ebo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\buffer\\vao.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\buffer\\vao.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\shader\\vertex.vert||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\shader\\vertex.vert||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\shader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\shader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\form\\form.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\form\\form.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec4d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec4d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\geometries\\plaingeometry\\polygon4.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\geometries\\plaingeometry\\polygon4.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\geometries\\geometryscaler\\angle.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\geometries\\geometryscaler\\angle.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec2d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec2d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vector.normalize.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vector.normalize.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\geometries\\geometryscaler\\angle.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\geometries\\geometryscaler\\angle.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec3d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec3d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\math\\linear\\matrix44.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpenvdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|solutionrelative:stgsharpenvdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpenvdebug\\stgsharpenvdebug.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|solutionrelative:stgsharpenvdebug\\stgsharpenvdebug.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\stgsharpdebug.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\stgsharpdebug.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\stgsharpdebug.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\stgsharpdebug.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|" + }, + { + "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\matinterface.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\matinterface.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{20CBFF26-6746-402E-992C-7B643E9423EB}|StgSharpC\\StgSharpC.vcxproj|D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\vector.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", @@ -34,18 +114,10 @@ "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\math\\graphic\\camera.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\graphics\\gl\\shaderedit\\uniform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\shader\\vertex.vert||{8B382828-6202-11D1-8870-0000F87579D2}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\shader\\vertex.vert||{8B382828-6202-11D1-8870-0000F87579D2}" - }, { "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\iglconvertable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\iglconvertable.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -58,22 +130,10 @@ "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\shadergenerator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\shadergenerator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec3d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec3d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\matrix22.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\matrix22.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\graphics\\gl\\shaderedit\\shader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\graphics\\gl\\shaderedit\\shader.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vector.getlength.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\geometries\\plaingeometry\\polygon5.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\geometries\\plaingeometry\\polygon5.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -122,10 +182,6 @@ "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vector.vectortransform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vector.vectortransform.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec4d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec4d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{20CBFF26-6746-402E-992C-7B643E9423EB}|StgSharpC\\StgSharpC.vcxproj|D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\StgSharpC.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", "RelativeMoniker": "D:0:0:{20CBFF26-6746-402E-992C-7B643E9423EB}|StgSharpC\\StgSharpC.vcxproj|solutionrelative:StgSharpC\\StgSharpC.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" @@ -142,10 +198,6 @@ "AbsoluteMoniker": "D:0:0:{20CBFF26-6746-402E-992C-7B643E9423EB}|StgSharpC\\StgSharpC.vcxproj|D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\ssgc_framework.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", "RelativeMoniker": "D:0:0:{20CBFF26-6746-402E-992C-7B643E9423EB}|StgSharpC\\StgSharpC.vcxproj|solutionrelative:StgSharpC\\ssgc_framework.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" }, - { - "AbsoluteMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpdebug\\math\\linear\\vec2d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{610B992B-BB34-49C3-9993-676C595FC12E}|StgSharpDebug\\StgSharpDebug.csproj|solutionrelative:stgsharpdebug\\math\\linear\\vec2d.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\graphics\\image.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\graphics\\image.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -178,10 +230,6 @@ "AbsoluteMoniker": "D:0:0:{63382F83-D04E-45B6-BDE6-443273F6D010}|BenchMark\\BenchMark.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\benchmark\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{63382F83-D04E-45B6-BDE6-443273F6D010}|BenchMark\\BenchMark.csproj|solutionrelative:benchmark\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharpenvdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{000EFD45-7F4D-47DB-8F3C-CD26612F0EAB}|StgsharpEnvDebug\\StgsharpEnvDebug.csproj|solutionrelative:stgsharpenvdebug\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|d:\\nitloadindustry\\\u7814\u7A76\u9879\u76EE\\1-flagship\\th2020\\projectfile\\\u6E90\u4EE3\u7801\\stgsharp\\graphics\\gl\\buffer\\ebo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{3EAF2EE6-FA9E-4F57-951F-7E6F8125DFBF}|StgSharp\\StgSharp.csproj|solutionrelative:stgsharp\\graphics\\gl\\buffer\\ebo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -267,11 +315,157 @@ "DocumentGroups": [ { "DockedWidth": 197, - "SelectedChildIndex": 31, + "SelectedChildIndex": 0, "Children": [ { "$type": "Document", - "DocumentIndex": 12, + "DocumentIndex": 0, + "Title": "GLpack.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\GLpack.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\GLpack.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\GLpack.cs", + "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\GLpack.cs", + "ViewState": "AQIAADYAAAAAAAAAAAA1wEsAAAAiAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T17:55:25.1Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "VAO.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\VAO.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\Buffer\\VAO.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\VAO.cs", + "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\Buffer\\VAO.cs", + "ViewState": "AQIAACQAAAAAAAAAAAAAACoAAAAnAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T17:51:29.819Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "EBO.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\EBO.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\Buffer\\EBO.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\EBO.cs", + "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\Buffer\\EBO.cs", + "ViewState": "AQIAAB4AAAAAAAAAAAAAACkAAAARAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T17:48:58.305Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "FBO.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\FBO.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\Buffer\\FBO.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\Buffer\\FBO.cs", + "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\Buffer\\FBO.cs", + "ViewState": "AQIAABEAAAAAAAAAAAAswCYAAAArAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T17:48:51.705Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "Form.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\Form\\Form.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\Form\\Form.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\Form\\Form.cs", + "RelativeToolTip": "StgSharpDebug\\Graphics\\Form\\Form.cs", + "ViewState": "AQIAAEQAAAAAAAAAAAAcwE8AAAAWAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T01:32:06.568Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "Polygon4.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\PlainGeometry\\Polygon4.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Geometries\\PlainGeometry\\Polygon4.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\PlainGeometry\\Polygon4.cs", + "RelativeToolTip": "StgSharpDebug\\Geometries\\PlainGeometry\\Polygon4.cs", + "ViewState": "AQIAAFMAAAAAAAAAAAAywF0AAAAJAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-10T01:20:29.483Z" + }, + { + "$type": "Document", + "DocumentIndex": 17, + "Title": "Vector.GetLength.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Math\\Linear\\Vector.GetLength.cs", + "RelativeDocumentMoniker": "StgSharp\\Math\\Linear\\Vector.GetLength.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Math\\Linear\\Vector.GetLength.cs", + "RelativeToolTip": "StgSharp\\Math\\Linear\\Vector.GetLength.cs", + "ViewState": "AQIAABoAAAAAAAAAAIAzwCoAAAAjAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-08T19:04:02.853Z" + }, + { + "$type": "Document", + "DocumentIndex": 19, + "Title": "Matrix44.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Math\\Linear\\Matrix44.cs", + "RelativeDocumentMoniker": "StgSharp\\Math\\Linear\\Matrix44.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Math\\Linear\\Matrix44.cs", + "RelativeToolTip": "StgSharp\\Math\\Linear\\Matrix44.cs", + "ViewState": "AQIAAIkAAAAAAAAAAAAtwLgAAAAfAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-07T12:10:12.495Z" + }, + { + "$type": "Document", + "DocumentIndex": 21, + "Title": "StgsharpEnvDebug", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgsharpEnvDebug\\StgsharpEnvDebug.csproj", + "RelativeDocumentMoniker": "StgsharpEnvDebug\\StgsharpEnvDebug.csproj", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgsharpEnvDebug\\StgsharpEnvDebug.csproj", + "RelativeToolTip": "StgsharpEnvDebug\\StgsharpEnvDebug.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-04-07T12:09:22.875Z" + }, + { + "$type": "Document", + "DocumentIndex": 22, + "Title": "StgSharpDebug", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\StgSharpDebug.csproj", + "RelativeDocumentMoniker": "StgSharpDebug\\StgSharpDebug.csproj", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\StgSharpDebug.csproj", + "RelativeToolTip": "StgSharpDebug\\StgSharpDebug.csproj", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-04-07T12:08:56.558Z" + }, + { + "$type": "Document", + "DocumentIndex": 23, + "Title": "StgSharpDebug.csproj", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\StgSharpDebug.csproj", + "RelativeDocumentMoniker": "StgSharpDebug\\StgSharpDebug.csproj", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\StgSharpDebug.csproj", + "RelativeToolTip": "StgSharpDebug\\StgSharpDebug.csproj", + "ViewState": "AQIAABIAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|", + "WhenOpened": "2024-04-07T12:08:51.612Z" + }, + { + "$type": "Document", + "DocumentIndex": 24, + "Title": "MatInterface.cs", + "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\MatInterface.cs", + "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\MatInterface.cs", + "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\MatInterface.cs", + "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\MatInterface.cs", + "ViewState": "AQIAAAkAAAAAAAAAAAAAAAAAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-04-07T07:26:54.413Z" + }, + { + "$type": "Document", + "DocumentIndex": 30, "Title": "ShaderStruct.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\ShaderStruct.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\ShaderStruct.cs", @@ -283,7 +477,7 @@ }, { "$type": "Document", - "DocumentIndex": 11, + "DocumentIndex": 29, "Title": "IglConvertable.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\IglConvertable.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\IglConvertable.cs", @@ -291,24 +485,23 @@ "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\IglConvertable.cs", "ViewState": "AQIAAAQAAAAAAAAAAIA0wBIAAAAjAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-05T19:06:01.02Z", - "EditorCaption": "" + "WhenOpened": "2024-04-05T19:06:01.02Z" }, { "$type": "Document", - "DocumentIndex": 17, + "DocumentIndex": 16, "Title": "Vector.GetLength.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vector.GetLength.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Vector.GetLength.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vector.GetLength.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\Vector.GetLength.cs", - "ViewState": "AQIAABAAAAAAAAAAAIAzwCAAAAAtAAAA", + "ViewState": "AQIAABwAAAAAAAAAAIA0wCUAAAAMAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-05T12:34:17.996Z" }, { "$type": "Document", - "DocumentIndex": 18, + "DocumentIndex": 33, "Title": "Polygon5.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\PlainGeometry\\Polygon5.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Geometries\\PlainGeometry\\Polygon5.cs", @@ -320,7 +513,7 @@ }, { "$type": "Document", - "DocumentIndex": 20, + "DocumentIndex": 35, "Title": "mat5.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\mat5.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\mat5.cs", @@ -332,7 +525,7 @@ }, { "$type": "Document", - "DocumentIndex": 21, + "DocumentIndex": 36, "Title": "mat6.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\mat6.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\mat6.cs", @@ -344,7 +537,7 @@ }, { "$type": "Document", - "DocumentIndex": 19, + "DocumentIndex": 34, "Title": "Polygon6.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\PlainGeometry\\Polygon6.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Geometries\\PlainGeometry\\Polygon6.cs", @@ -356,7 +549,7 @@ }, { "$type": "Document", - "DocumentIndex": 22, + "DocumentIndex": 37, "Title": "Matrix34.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix34.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix34.cs", @@ -368,7 +561,7 @@ }, { "$type": "Document", - "DocumentIndex": 23, + "DocumentIndex": 38, "Title": "Matrix33.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix33.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix33.cs", @@ -380,7 +573,7 @@ }, { "$type": "Document", - "DocumentIndex": 24, + "DocumentIndex": 39, "Title": "Matrix32.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix32.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix32.cs", @@ -392,7 +585,7 @@ }, { "$type": "Document", - "DocumentIndex": 25, + "DocumentIndex": 40, "Title": "Matrix24.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix24.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix24.cs", @@ -404,7 +597,7 @@ }, { "$type": "Document", - "DocumentIndex": 26, + "DocumentIndex": 41, "Title": "Matrix23.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix23.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix23.cs", @@ -416,7 +609,7 @@ }, { "$type": "Document", - "DocumentIndex": 15, + "DocumentIndex": 32, "Title": "Matrix22.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix22.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix22.cs", @@ -428,7 +621,7 @@ }, { "$type": "Document", - "DocumentIndex": 28, + "DocumentIndex": 43, "Title": "Matrix42.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix42.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix42.cs", @@ -440,7 +633,7 @@ }, { "$type": "Document", - "DocumentIndex": 27, + "DocumentIndex": 42, "Title": "Matrix43.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix43.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix43.cs", @@ -452,7 +645,7 @@ }, { "$type": "Document", - "DocumentIndex": 29, + "DocumentIndex": 44, "Title": "Vector.VectorTransform.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vector.VectorTransform.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Vector.VectorTransform.cs", @@ -464,20 +657,19 @@ }, { "$type": "Document", - "DocumentIndex": 3, + "DocumentIndex": 14, "Title": "Vector.Normalize.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vector.Normalize.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Vector.Normalize.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vector.Normalize.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\Vector.Normalize.cs", - "ViewState": "AQIAAB0AAAAAAAAAAAAswC4AAAAjAAAA", + "ViewState": "AQIAABwAAAAAAAAAAAApwDQAAAAAAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-05T11:15:25.94Z", - "EditorCaption": "" + "WhenOpened": "2024-04-05T11:15:25.94Z" }, { "$type": "Document", - "DocumentIndex": 32, + "DocumentIndex": 46, "Title": "stb_image.c", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\stb_image.c", "RelativeDocumentMoniker": "StgSharpC\\stb_image.c", @@ -489,7 +681,7 @@ }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 25, "Title": "vector.c", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\vector.c", "RelativeDocumentMoniker": "StgSharpC\\vector.c", @@ -497,12 +689,11 @@ "RelativeToolTip": "StgSharpC\\vector.c", "ViewState": "AQIAAAAAAAAAAAAAAAAAABYAAAAYAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", - "WhenOpened": "2024-04-05T04:55:01.943Z", - "EditorCaption": "" + "WhenOpened": "2024-04-05T04:55:01.943Z" }, { "$type": "Document", - "DocumentIndex": 31, + "DocumentIndex": 45, "Title": "StgSharpC.h", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\StgSharpC.h", "RelativeDocumentMoniker": "StgSharpC\\StgSharpC.h", @@ -514,7 +705,7 @@ }, { "$type": "Document", - "DocumentIndex": 34, + "DocumentIndex": 48, "Title": "ssgc_framework.h", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\ssgc_framework.h", "RelativeDocumentMoniker": "StgSharpC\\ssgc_framework.h", @@ -526,108 +717,104 @@ }, { "$type": "Document", - "DocumentIndex": 35, + "DocumentIndex": 13, "Title": "vec2d.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\vec2d.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\vec2d.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\vec2d.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\vec2d.cs", - "ViewState": "AQIAACcAAAAAAAAAAAAAADIAAAA6AAAA", + "ViewState": "AQIAAF8AAAAAAAAAAAAuwHAAAAAAAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-05T02:02:28.988Z" }, { "$type": "Document", - "DocumentIndex": 14, + "DocumentIndex": 15, "Title": "vec3d.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\vec3d.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\vec3d.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\vec3d.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\vec3d.cs", - "ViewState": "AQIAACMAAAAAAAAAAAApwCkAAAAYAAAA", + "ViewState": "AQIAAMgAAAAAAAAAAAAMwMoAAAAIAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-05T02:02:18.194Z" }, { "$type": "Document", - "DocumentIndex": 30, + "DocumentIndex": 10, "Title": "Vec4d.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vec4d.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Vec4d.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Vec4d.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\Vec4d.cs", - "ViewState": "AQIAAC4AAAAAAAAAAAA9wCoAAAAAAAAA", + "ViewState": "AQIAADQAAAAAAAAAAAAQwD8AAAAWAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-05T02:00:23.829Z" }, { "$type": "Document", - "DocumentIndex": 2, + "DocumentIndex": 18, "Title": "Matrix44.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix44.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Linear\\Matrix44.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Linear\\Matrix44.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Linear\\Matrix44.cs", - "ViewState": "AQIAAEQAAAAAAAAAAAAswFUAAAAXAAAA", + "ViewState": "AQIAABwAAAAAAAAAAIAzwCwAAAAhAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-05T01:40:53.572Z", - "EditorCaption": "" + "WhenOpened": "2024-04-05T01:40:53.572Z" }, { "$type": "Document", - "DocumentIndex": 1, + "DocumentIndex": 4, "Title": "Program.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Program.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Program.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Program.cs", "RelativeToolTip": "StgSharpDebug\\Program.cs", - "ViewState": "AQIAAHoAAAAAAAAAAAAswIUAAAA4AAAA", + "ViewState": "AQIAADsAAAAAAAAAAAA0wEwAAAASAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-04T08:52:20.555Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 12, "Title": "Angle.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\GeometryScaler\\Angle.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Geometries\\GeometryScaler\\Angle.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Geometries\\GeometryScaler\\Angle.cs", "RelativeToolTip": "StgSharpDebug\\Geometries\\GeometryScaler\\Angle.cs", - "ViewState": "AQIAAEwAAAAAAAAAAAA0wFYAAAA6AAAA", + "ViewState": "AQIAAEsAAAAAAAAAAAAtwFYAAAA6AAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-04T14:31:04.075Z", - "EditorCaption": "" + "WhenOpened": "2024-04-04T14:31:04.075Z" }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 5, "Title": "vertex.vert", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Shader\\vertex.vert", "RelativeDocumentMoniker": "StgSharpDebug\\Shader\\vertex.vert", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Shader\\vertex.vert", "RelativeToolTip": "StgSharpDebug\\Shader\\vertex.vert", - "ViewState": "AQIAAAAAAAAAAAAAAAAAAAoAAAAVAAAA", + "ViewState": "AQIAAAAAAAAAAAAAAAAAABMAAAAQAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|", - "WhenOpened": "2024-04-04T08:52:41.724Z", - "EditorCaption": "" + "WhenOpened": "2024-04-04T08:52:41.724Z" }, { "$type": "Document", - "DocumentIndex": 8, + "DocumentIndex": 6, "Title": "Uniform.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Uniform.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Uniform.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Uniform.cs", "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Uniform.cs", - "ViewState": "AQIAAGoAAAAAAAAAAIAywFIAAAAtAAAA", + "ViewState": "AQIAAMcAAAAAAAAAAAD4v80AAAAuAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-04T08:46:15.45Z", - "EditorCaption": "" + "WhenOpened": "2024-04-04T08:46:15.45Z" }, { "$type": "Document", - "DocumentIndex": 13, + "DocumentIndex": 31, "Title": "ShaderGenerator.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\ShaderGenerator.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\ShaderGenerator.cs", @@ -639,32 +826,31 @@ }, { "$type": "Document", - "DocumentIndex": 16, + "DocumentIndex": 8, "Title": "Shader.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Shader.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Shader.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Shader.cs", "RelativeToolTip": "StgSharpDebug\\Graphics\\GL\\ShaderEdit\\Shader.cs", - "ViewState": "AQIAAEYAAAAAAAAAAAAWwFsAAAAsAAAA", + "ViewState": "AQIAAHMAAAAAAAAAAAAlwH4AAAAIAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2024-04-04T08:46:00.769Z" }, { "$type": "Document", - "DocumentIndex": 0, + "DocumentIndex": 7, "Title": "Camera.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Graphic\\Camera.cs", "RelativeDocumentMoniker": "StgSharpDebug\\Math\\Graphic\\Camera.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpDebug\\Math\\Graphic\\Camera.cs", "RelativeToolTip": "StgSharpDebug\\Math\\Graphic\\Camera.cs", - "ViewState": "AQIAAN0AAAAAAAAAAIAywOcAAAAJAAAA", + "ViewState": "AQIAAMQAAAAAAAAAAAAswM0AAAAIAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-04T08:45:44.658Z", - "EditorCaption": "" + "WhenOpened": "2024-04-04T08:45:44.658Z" }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 27, "Title": "Camera.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Math\\Graphic\\Camera.cs", "RelativeDocumentMoniker": "StgSharp\\Math\\Graphic\\Camera.cs", @@ -672,12 +858,11 @@ "RelativeToolTip": "StgSharp\\Math\\Graphic\\Camera.cs", "ViewState": "AQIAALcAAAAAAAAAAIAzwMcAAABfAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-04-04T08:41:59.488Z", - "EditorCaption": "" + "WhenOpened": "2024-04-04T08:41:59.488Z" }, { "$type": "Document", - "DocumentIndex": 36, + "DocumentIndex": 49, "Title": "Image.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Image.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Image.cs", @@ -689,7 +874,7 @@ }, { "$type": "Document", - "DocumentIndex": 39, + "DocumentIndex": 52, "Title": "GLIO.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Control\\IO\\GLIO.cs", "RelativeDocumentMoniker": "StgSharp\\Control\\IO\\GLIO.cs", @@ -701,7 +886,7 @@ }, { "$type": "Document", - "DocumentIndex": 38, + "DocumentIndex": 51, "Title": "GLpack.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\GLpack.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\GLpack.cs", @@ -713,7 +898,7 @@ }, { "$type": "Document", - "DocumentIndex": 41, + "DocumentIndex": 54, "Title": "glApiManager.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\glApiManager.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\glApiManager.cs", @@ -725,7 +910,7 @@ }, { "$type": "Document", - "DocumentIndex": 40, + "DocumentIndex": 53, "Title": "GLhandle.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\GLhandle.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\GLhandle.cs", @@ -737,7 +922,7 @@ }, { "$type": "Document", - "DocumentIndex": 43, + "DocumentIndex": 56, "Title": "Program.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\BenchMark\\Program.cs", "RelativeDocumentMoniker": "BenchMark\\Program.cs", @@ -749,7 +934,7 @@ }, { "$type": "Document", - "DocumentIndex": 33, + "DocumentIndex": 47, "Title": "ssgc_internal.h", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\ssgc_internal.h", "RelativeDocumentMoniker": "StgSharpC\\ssgc_internal.h", @@ -761,7 +946,7 @@ }, { "$type": "Document", - "DocumentIndex": 47, + "DocumentIndex": 59, "Title": "BufferObjectBase.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\Buffer\\BufferObjectBase.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\Buffer\\BufferObjectBase.cs", @@ -773,7 +958,7 @@ }, { "$type": "Document", - "DocumentIndex": 48, + "DocumentIndex": 60, "Title": "GemoryException.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Geometries\\PlainGeometry\\GemoryException.cs", "RelativeDocumentMoniker": "StgSharp\\Geometries\\PlainGeometry\\GemoryException.cs", @@ -785,7 +970,7 @@ }, { "$type": "Document", - "DocumentIndex": 45, + "DocumentIndex": 57, "Title": "EBO.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\Buffer\\EBO.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\Buffer\\EBO.cs", @@ -797,7 +982,7 @@ }, { "$type": "Document", - "DocumentIndex": 46, + "DocumentIndex": 58, "Title": "VBO.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\Buffer\\VBO.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\Buffer\\VBO.cs", @@ -809,7 +994,7 @@ }, { "$type": "Document", - "DocumentIndex": 42, + "DocumentIndex": 55, "Title": "VAO.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\Buffer\\VAO.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\Buffer\\VAO.cs", @@ -821,7 +1006,7 @@ }, { "$type": "Document", - "DocumentIndex": 37, + "DocumentIndex": 50, "Title": "Shader.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\ShaderEdit\\Shader.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\ShaderEdit\\Shader.cs", @@ -833,7 +1018,7 @@ }, { "$type": "Document", - "DocumentIndex": 49, + "DocumentIndex": 61, "Title": "FormThreading.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Form\\FormThreading.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Form\\FormThreading.cs", @@ -845,7 +1030,7 @@ }, { "$type": "Document", - "DocumentIndex": 50, + "DocumentIndex": 62, "Title": "FormThreadAttribute.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Form\\FormThreadAttribute.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Form\\FormThreadAttribute.cs", @@ -857,7 +1042,7 @@ }, { "$type": "Document", - "DocumentIndex": 52, + "DocumentIndex": 64, "Title": "FrameAsyncThread.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Form\\FrameAsyncThread.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Form\\FrameAsyncThread.cs", @@ -869,7 +1054,7 @@ }, { "$type": "Document", - "DocumentIndex": 65, + "DocumentIndex": 77, "Title": "immintrin.h", "DocumentMoniker": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.39.33519\\include\\immintrin.h", "ToolTip": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.39.33519\\include\\immintrin.h", @@ -879,7 +1064,7 @@ }, { "$type": "Document", - "DocumentIndex": 53, + "DocumentIndex": 65, "Title": "mat4.c", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\mat4.c", "RelativeDocumentMoniker": "StgSharpC\\mat4.c", @@ -891,7 +1076,7 @@ }, { "$type": "Document", - "DocumentIndex": 55, + "DocumentIndex": 67, "Title": "Square.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Geometries\\PlainGeometry\\Square.cs", "RelativeDocumentMoniker": "StgSharp\\Geometries\\PlainGeometry\\Square.cs", @@ -903,7 +1088,7 @@ }, { "$type": "Document", - "DocumentIndex": 54, + "DocumentIndex": 66, "Title": "TimeSpanProvider.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Logic\\TimeSpanProvider.cs", "RelativeDocumentMoniker": "StgSharp\\Logic\\TimeSpanProvider.cs", @@ -915,7 +1100,7 @@ }, { "$type": "Document", - "DocumentIndex": 9, + "DocumentIndex": 28, "Title": "Uniform.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\GL\\ShaderEdit\\Uniform.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\GL\\ShaderEdit\\Uniform.cs", @@ -923,12 +1108,11 @@ "RelativeToolTip": "StgSharp\\Graphics\\GL\\ShaderEdit\\Uniform.cs", "ViewState": "AQIAACEAAAAAAAAAAAAWwC8AAAAIAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2024-03-18T18:25:24.623Z", - "EditorCaption": "" + "WhenOpened": "2024-03-18T18:25:24.623Z" }, { "$type": "Document", - "DocumentIndex": 57, + "DocumentIndex": 69, "Title": "TimeProvider.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Environment\\TimeProvider.cs", "RelativeDocumentMoniker": "StgSharp\\Environment\\TimeProvider.cs", @@ -940,7 +1124,7 @@ }, { "$type": "Document", - "DocumentIndex": 56, + "DocumentIndex": 68, "Title": "TimeSourceProvider.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Logic\\TimeSourceProvider.cs", "RelativeDocumentMoniker": "StgSharp\\Logic\\TimeSourceProvider.cs", @@ -952,7 +1136,7 @@ }, { "$type": "Document", - "DocumentIndex": 58, + "DocumentIndex": 70, "Title": "StructDefine.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Define\\StructDefine.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Define\\StructDefine.cs", @@ -964,7 +1148,7 @@ }, { "$type": "Document", - "DocumentIndex": 51, + "DocumentIndex": 63, "Title": "Form.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharp\\Graphics\\Form\\Form.cs", "RelativeDocumentMoniker": "StgSharp\\Graphics\\Form\\Form.cs", @@ -976,7 +1160,7 @@ }, { "$type": "Document", - "DocumentIndex": 6, + "DocumentIndex": 26, "Title": "StgSharpC.c", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgSharpC\\StgSharpC.c", "RelativeDocumentMoniker": "StgSharpC\\StgSharpC.c", @@ -984,12 +1168,11 @@ "RelativeToolTip": "StgSharpC\\StgSharpC.c", "ViewState": "AQIAAAAAAAAAAAAAAAAAABAAAAA7AAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", - "WhenOpened": "2024-03-15T18:54:32.768Z", - "EditorCaption": "" + "WhenOpened": "2024-03-15T18:54:32.768Z" }, { "$type": "Document", - "DocumentIndex": 59, + "DocumentIndex": 71, "Title": "Windows.Win32.PInvoke.USER32.dll.g.cs", "DocumentMoniker": "C:\\Users\\Nitlo\\AppData\\Local\\Temp\\VSGeneratedDocuments\\2c3332ae-ceb8-c175-356d-4c8856697af4\\Windows.Win32.PInvoke.USER32.dll.g.cs", "ToolTip": "Windows.Win32.PInvoke.USER32.dll.g.cs [\u7531 Microsoft.Windows.CsWin32.SourceGenerator \u751F\u6210]", @@ -999,7 +1182,7 @@ }, { "$type": "Document", - "DocumentIndex": 62, + "DocumentIndex": 74, "Title": "Windows.Win32.PInvoke.Gdi32.g.cs", "DocumentMoniker": "C:\\Users\\Nitlo\\AppData\\Local\\Temp\\VSGeneratedDocuments\\79ac1c40-7151-2ce1-597a-25095d944cf9\\Windows.Win32.PInvoke.Gdi32.g.cs", "ToolTip": "Windows.Win32.PInvoke.Gdi32.g.cs [\u7531 Microsoft.Windows.CsWin32.SourceGenerator \u751F\u6210]", @@ -1009,7 +1192,7 @@ }, { "$type": "Document", - "DocumentIndex": 61, + "DocumentIndex": 73, "Title": "Windows.Win32.PInvoke.OPENGL32.g.cs", "DocumentMoniker": "C:\\Users\\Nitlo\\AppData\\Local\\Temp\\VSGeneratedDocuments\\0c87b10d-89a1-0d65-5307-332433f23145\\Windows.Win32.PInvoke.OPENGL32.g.cs", "ToolTip": "Windows.Win32.PInvoke.OPENGL32.g.cs [\u7531 Microsoft.Windows.CsWin32.SourceGenerator \u751F\u6210]", @@ -1019,7 +1202,7 @@ }, { "$type": "Document", - "DocumentIndex": 60, + "DocumentIndex": 72, "Title": "readme.txt", "DocumentMoniker": "C:\\Users\\Nitlo\\.nuget\\packages\\microsoft.windows.cswin32\\0.3.49-beta\\readme.txt", "ToolTip": "C:\\Users\\Nitlo\\.nuget\\packages\\microsoft.windows.cswin32\\0.3.49-beta\\readme.txt", @@ -1029,7 +1212,7 @@ }, { "$type": "Document", - "DocumentIndex": 63, + "DocumentIndex": 75, "Title": "Microsoft.CppCommon.targets", "DocumentMoniker": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets", "ToolTip": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\MSBuild\\Microsoft\\VC\\v170\\Microsoft.CppCommon.targets", @@ -1039,7 +1222,7 @@ }, { "$type": "Document", - "DocumentIndex": 64, + "DocumentIndex": 76, "Title": "List.cs", "DocumentMoniker": "C:\\Users\\Nitlo\\AppData\\Local\\SourceServer\\a49b3a21a68db01290f63b8f22e4a9e58546e0a62fe2ff69b472e6b354d1bcea\\src\\libraries\\System.Private.CoreLib\\src\\System\\Collections\\Generic\\List.cs", "ToolTip": "C:\\Users\\Nitlo\\AppData\\Local\\SourceServer\\a49b3a21a68db01290f63b8f22e4a9e58546e0a62fe2ff69b472e6b354d1bcea\\src\\libraries\\System.Private.CoreLib\\src\\System\\Collections\\Generic\\List.cs", @@ -1048,13 +1231,13 @@ }, { "$type": "Document", - "DocumentIndex": 44, + "DocumentIndex": 20, "Title": "Program.cs", "DocumentMoniker": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgsharpEnvDebug\\Program.cs", "RelativeDocumentMoniker": "StgsharpEnvDebug\\Program.cs", "ToolTip": "D:\\NitloadIndustry\\\u7814\u7A76\u9879\u76EE\\1-Flagship\\TH2020\\ProjectFile\\\u6E90\u4EE3\u7801\\StgsharpEnvDebug\\Program.cs", "RelativeToolTip": "StgsharpEnvDebug\\Program.cs", - "ViewState": "AQIAAAIAAAAAAAAAAADgvw4AAAAFAAAA", + "ViewState": "AQIAAAEAAAAAAAAAAAAcwBAAAAAPAAAA", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2023-12-20T18:58:34.322Z" } diff --git a/�代�/.vs/StgSharpDevelop/v17/Solution.VC.db b/�代�/.vs/StgSharpDevelop/v17/Solution.VC.db index ff680732..9e2dab30 100644 Binary files a/�代�/.vs/StgSharpDevelop/v17/Solution.VC.db and b/�代�/.vs/StgSharpDevelop/v17/Solution.VC.db differ diff --git a/�代�/.vs/StgSharpDevelop/v17/fileList.bin b/�代�/.vs/StgSharpDevelop/v17/fileList.bin index 3106d916..b3b53479 100644 Binary files a/�代�/.vs/StgSharpDevelop/v17/fileList.bin and b/�代�/.vs/StgSharpDevelop/v17/fileList.bin differ diff --git a/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfo.cs b/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfo.cs index 7f9d347f..8e055abf 100644 --- a/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfo.cs +++ b/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("BenchMark")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b207f16616b7bd967d647a809cc27e7174063451")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("BenchMark")] [assembly: System.Reflection.AssemblyTitleAttribute("BenchMark")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfoInputs.cache b/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfoInputs.cache index 2db69dc7..24b1b192 100644 --- a/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfoInputs.cache +++ b/�代�/BenchMark/obj/Debug/net6.0/BenchMark.AssemblyInfoInputs.cache @@ -1 +1 @@ -4ce4fc9d63e9d0c453b50b0a1213da7fbcc35782793b4a1147ab0fb46cf62bb0 +366f5c2b7d0e718099c3e85a9ebf2cbf2a21cf7a6057af17e10cdb8df21f1f72 diff --git a/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfo.cs b/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfo.cs index d95efca4..e489daa1 100644 --- a/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfo.cs +++ b/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("BenchMark")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b207f16616b7bd967d647a809cc27e7174063451")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("BenchMark")] [assembly: System.Reflection.AssemblyTitleAttribute("BenchMark")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfoInputs.cache b/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfoInputs.cache index 91f29c1f..90c5ac6f 100644 --- a/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfoInputs.cache +++ b/�代�/BenchMark/obj/Release/net6.0/BenchMark.AssemblyInfoInputs.cache @@ -1 +1 @@ -9d16836e13eaf895ecadfb558811d26297a9ffd64900f90ccf2eb7065c8ba7bc +37e23d756ce4575fbf467937553f24d34014d9c297f0c533ffac10c6ae12e798 diff --git a/�代�/Output/x64/Debug/net6.0/SS_errorlog.log b/�代�/Output/x64/Debug/net6.0/SS_errorlog.log index e69de29b..8115b1e5 100644 --- a/�代�/Output/x64/Debug/net6.0/SS_errorlog.log +++ b/�代�/Output/x64/Debug/net6.0/SS_errorlog.log @@ -0,0 +1,290 @@ + + + + +Info @ 2024-04-10T17:31:18.5750842+08:00 +Program start +Info @ 2024-04-10T17:31:18.6873832+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T17:31:18.6971576+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T17:34:29.5675686+08:00 +Program start +Info @ 2024-04-10T17:34:31.0505972+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T17:34:31.0747380+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T17:35:49.1709482+08:00 +Program start +Info @ 2024-04-10T17:35:49.7879359+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T17:35:49.8002369+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T17:55:03.8553506+08:00 +Program start +Info @ 2024-04-10T17:55:03.9730411+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T17:55:03.9819986+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:32:49.0545894+08:00 +Program start +Info @ 2024-04-10T20:32:49.2783385+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:32:49.2895609+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:33:08.6687250+08:00 +Program start +Info @ 2024-04-10T20:33:08.7880384+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:33:08.7966554+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:35:12.8904986+08:00 +Program start +Info @ 2024-04-10T20:35:13.0053044+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:35:13.0157656+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:35:50.4187466+08:00 +Program start +Info @ 2024-04-10T20:35:50.5406890+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:35:50.5494842+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:36:11.1335696+08:00 +Program start +Info @ 2024-04-10T20:36:11.2421395+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:36:11.2510348+08:00 +No supported OpenGL extensions are found. + + + + +Info @ 2024-04-10T20:37:28.5656935+08:00 +Program start +Info @ 2024-04-10T20:37:28.6826337+08:00 +Find core OpenGL version. +Successfully load all OpenGL 1.0 APIs +Successfully load all OpenGL 1.1 APIs +Successfully load all OpenGL 1.2 APIs +Successfully load all OpenGL 1.3 APIs +Successfully load all OpenGL 1.4 APIs +Successfully load all OpenGL 1.5 APIs +Successfully load all OpenGL 2.0 APIs +Successfully load all OpenGL 2.1 APIs +Successfully load all OpenGL 3.0 APIs +Successfully load all OpenGL 3.1 APIs +Successfully load all OpenGL 3.2 APIs +Successfully load all OpenGL 3.3 APIs +Successfully load all OpenGL 4.0 APIs +Successfully load all OpenGL 4.1 APIs +Successfully load all OpenGL 4.2 APIs +Successfully load all OpenGL 4.3 APIs +Successfully load all OpenGL 4.4 APIs +Successfully load all OpenGL 4.5 APIs +Successfully load all OpenGL 4.6 APIs +Info @ 2024-04-10T20:37:28.6917855+08:00 +No supported OpenGL extensions are found. diff --git a/�代�/Output/x64/Debug/net6.0/Shader/vertex.vert b/�代�/Output/x64/Debug/net6.0/Shader/vertex.vert index 7fefa48c..d3050afe 100644 --- a/�代�/Output/x64/Debug/net6.0/Shader/vertex.vert +++ b/�代�/Output/x64/Debug/net6.0/Shader/vertex.vert @@ -8,8 +8,7 @@ out vec4 TexColor; out vec2 TexCoord; uniform vec4 color; -uniform mat4x4 lookAt; -uniform mat4x4 projection; +uniform mat4x4 camera; void main() { @@ -21,10 +20,10 @@ void main() 0,0,1,0, 0,0,0,1 ); - vec4 temp = (vec4(aPos.xyz,1.0) + vec4(color.yz-vec2(0.5,0.5),0.0,0.0)) * rotation; - gl_Position = projection * lookAt * temp; TexColor = color; TexCoord = aTextCoord; + vec4 temp = (vec4(aPos.xyz,1.0) + vec4(color.yz-vec2(0.5,0.5),0.0,0.0)) * rotation; + gl_Position = /**/ camera * /**/ temp; } //struct diff --git a/�代�/Output/x64/Debug/net6.0/StgSharpC.dll b/�代�/Output/x64/Debug/net6.0/StgSharpC.dll index ee7b2ba1..e451fb23 100644 Binary files a/�代�/Output/x64/Debug/net6.0/StgSharpC.dll and b/�代�/Output/x64/Debug/net6.0/StgSharpC.dll differ diff --git a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.dll b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.dll index fe1104c5..0d6d2699 100644 Binary files a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.dll and b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.dll differ diff --git a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.exe b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.exe index 2eefd6f3..5f012d06 100644 Binary files a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.exe and b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.exe differ diff --git a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.pdb b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.pdb index 5aa4b2c5..2ed8405d 100644 Binary files a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.pdb and b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.pdb differ diff --git a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.xml b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.xml index 313cf22e..08e8e6fb 100644 --- a/�代�/Output/x64/Debug/net6.0/StgSharpDebug.xml +++ b/�代�/Output/x64/Debug/net6.0/StgSharpDebug.xml @@ -64,12 +64,12 @@ Set all necessary metadata to current form instance - + Resize the current form - A (width,height) representing the new size of current form + A (width,height) representing the new size of current form @@ -79,15 +79,15 @@ New width of the window New height of the window - + Set the size limit of current form - Minimun size of current form. In form of a of (width,height) + Minimun size of current form. In form of a of (width,height) - Maximum size of current form. In form of a of (width,height) + Maximum size of current form. In form of a of (width,height) @@ -412,7 +412,7 @@ An IEEE-754 double precision floating-point value, clamped to the range [0,1]. - + A two dimension vector defined by two elements. Vec2Ds in StgSharp are defaultly usaed as colum vector. diff --git a/�代�/StgSharp/Entities/IEntity.cs b/�代�/StgSharp/Entities/IEntity.cs index e908b5b0..70295c58 100644 --- a/�代�/StgSharp/Entities/IEntity.cs +++ b/�代�/StgSharp/Entities/IEntity.cs @@ -65,7 +65,7 @@ namespace StgSharp /// /// A 2D vector presenting the position of an enemy entity, position can also be visited by X, Y /// - public Vec2d Location { get; } + public vec2d Location { get; } public string Texture { get; set; } diff --git a/�代�/StgSharp/Entities/Launcher.cs b/�代�/StgSharp/Entities/Launcher.cs index a41fb1fb..e2e9f958 100644 --- a/�代�/StgSharp/Entities/Launcher.cs +++ b/�代�/StgSharp/Entities/Launcher.cs @@ -41,7 +41,7 @@ namespace StgSharp *用于�射其他的实体,主�是�弹 和 掉�物 */ - internal Vec2d _center; //�射器的�考�置,�动轨迹的方程应当基于这个�考点构建 + internal vec2d _center; //�射器的�考�置,�动轨迹的方程应当基于这个�考点构建 internal Counter _internalParameter; //�射器的内部计时器 internal uint[] launchtick; //�射�弹的内部计时 diff --git a/�代�/StgSharp/Geometries/PlainGeometry/Cordinate.cs b/�代�/StgSharp/Geometries/PlainGeometry/Cordinate.cs index d5b77d4f..215abcca 100644 --- a/�代�/StgSharp/Geometries/PlainGeometry/Cordinate.cs +++ b/�代�/StgSharp/Geometries/PlainGeometry/Cordinate.cs @@ -80,7 +80,7 @@ namespace StgSharp.Geometries public vec3d axis_V => axis.colum1; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public vec3d GetRealLocate(Vec2d raletiveLocation) + public vec3d GetRealLocate(vec2d raletiveLocation) { return origin + axis.VerticalVecMultiply(raletiveLocation); } diff --git a/�代�/StgSharp/Geometries/PlainGeometry/Polygon4.cs b/�代�/StgSharp/Geometries/PlainGeometry/Polygon4.cs index ef34bc8f..2ff65fdf 100644 --- a/�代�/StgSharp/Geometries/PlainGeometry/Polygon4.cs +++ b/�代�/StgSharp/Geometries/PlainGeometry/Polygon4.cs @@ -50,10 +50,10 @@ namespace StgSharp.Geometries } public Polygon4(PartialPlainCoordinate coordinate, - Vec2d topLeft, - Vec2d topRight, - Vec2d bottomRight, - Vec2d bottomLeft, + vec2d topLeft, + vec2d topRight, + vec2d bottomRight, + vec2d bottomLeft, bool Orth ) { @@ -76,8 +76,8 @@ namespace StgSharp.Geometries textureFrame.mat.colum1 = maxCoord; textureFrame.mat.colum3 = minCoord; - textureFrame.Colum0 = new Vec2d(minCoord.X, maxCoord.Y); - textureFrame.Colum2 = new Vec2d(maxCoord.X, minCoord.Y); + textureFrame.Colum0 = new vec2d(minCoord.X, maxCoord.Y); + textureFrame.Colum2 = new vec2d(maxCoord.X, minCoord.Y); } public Polygon4( @@ -93,10 +93,10 @@ namespace StgSharp.Geometries vertexMat.mat.colum3 = new Vector4(v3x, v3y, v3z, 0); } - public GetLocationHandler MovVertex0Operaion => moveVertex0Operation; - public GetLocationHandler MovVertex1Operaion => moveVertex1Operation; - public GetLocationHandler MovVertex2Operaion => moveVertex2Operation; - public GetLocationHandler MovVertex3Operaion => moveVertex3Operation; + public GetLocationHandler MovVertex0Operation => moveVertex0Operation; + public GetLocationHandler MovVertex1Operation => moveVertex1Operation; + public GetLocationHandler MovVertex2Operation => moveVertex2Operation; + public GetLocationHandler MovVertex3Operation => moveVertex3Operation; public Point Vertex0 { diff --git a/�代�/StgSharp/Geometries/PlainGeometry/Rectangle.cs b/�代�/StgSharp/Geometries/PlainGeometry/Rectangle.cs index e812738d..5f3fbee9 100644 --- a/�代�/StgSharp/Geometries/PlainGeometry/Rectangle.cs +++ b/�代�/StgSharp/Geometries/PlainGeometry/Rectangle.cs @@ -49,8 +49,8 @@ namespace StgSharp.Geometries v3x, v2y, v3z ) { - Vec2d side0 = vertexMat.Colum0 - vertexMat.Colum1; - Vec2d side1 = vertexMat.Colum2 - vertexMat.Colum1; + vec2d side0 = vertexMat.Colum0 - vertexMat.Colum1; + vec2d side1 = vertexMat.Colum2 - vertexMat.Colum1; if (side0.Cross(side1) == 0) { diff --git a/�代�/StgSharp/Graphics/Form/Form.cs b/�代�/StgSharp/Graphics/Form/Form.cs index bbdc8e55..70da823d 100644 --- a/�代�/StgSharp/Graphics/Form/Form.cs +++ b/�代�/StgSharp/Graphics/Form/Form.cs @@ -76,8 +76,8 @@ namespace StgSharp.Graphics { Interlocked.Exchange(ref _frameSpeed, _frameCount); Interlocked.Exchange(ref _frameCount, 0); - Console.Clear(); - Console.WriteLine(_frameSpeed); + //Console.Clear(); + //Console.WriteLine(_frameSpeed); }); } @@ -102,9 +102,9 @@ namespace StgSharp.Graphics /// /// Width of this form, represent in /// - public Vec2d Size + public vec2d Size { - get => new Vec2d(width, height); + get => new vec2d(width, height); set { width = (int)value.X; @@ -204,10 +204,10 @@ namespace StgSharp.Graphics /// Resize the current form /// /// - /// A (width,height) representing the new size of current form + /// A (width,height) representing the new size of current form /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetSize(Vec2d size) + public void SetSize(vec2d size) { this.Size = size; InternalIO.glfwSetWindowSize(this.windowID, (int)size.X, (int)size.Y); @@ -231,13 +231,13 @@ namespace StgSharp.Graphics /// Set the size limit of current form /// /// - /// Minimun size of current form. In form of a of (width,height) + /// Minimun size of current form. In form of a of (width,height) /// /// - /// Maximum size of current form. In form of a of (width,height) + /// Maximum size of current form. In form of a of (width,height) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetSizeLimit(Vec2d minSize, Vec2d maxSize) + public void SetSizeLimit(vec2d minSize, vec2d maxSize) { InternalIO.glfwSetWindowSizeLimits( this.windowID, diff --git a/�代�/StgSharp/Graphics/GL/Buffer/EBO.cs b/�代�/StgSharp/Graphics/GL/Buffer/EBO.cs index 95188ef3..343184e7 100644 --- a/�代�/StgSharp/Graphics/GL/Buffer/EBO.cs +++ b/�代�/StgSharp/Graphics/GL/Buffer/EBO.cs @@ -39,7 +39,7 @@ using System.Text; namespace StgSharp.Graphics { /// - /// A collecion of handle to Element Buffer Object in OpenGL. + /// A collection of handle to Element Buffer Object in OpenGL. /// Each value indexed from instance of this class this /// is the only handle to one Element Buffer Object. /// diff --git a/�代�/StgSharp/Graphics/GL/Buffer/FBO.cs b/�代�/StgSharp/Graphics/GL/Buffer/FBO.cs new file mode 100644 index 00000000..d16ca341 --- /dev/null +++ b/�代�/StgSharp/Graphics/GL/Buffer/FBO.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Graphics +{ + public enum FrameBufferTarget:uint + { + Read = GLconst.READ_FRAMEBUFFER, + All = GLconst.FRAMEBUFFER, + Draw = GLconst.DRAW_FRAMEBUFFER, + } + + public class FrameBuffer : BufferObjectBase + { + internal unsafe FrameBuffer(int count, IntPtr contextBinding) + { + binding = contextBinding; + _bufferHandle = new glHandleSet(count); + ((GLcontext*)binding)->glGenFramebuffers((uint)count,_bufferHandle.handle); + } + + /// + /// Bind the frame buffer object with name frame buffer to the frame buffer target specified by target. + /// will be set as default target. + /// + /// Index of object to be binded in handle set + public unsafe override void Bind(int index) + { + ((GLcontext*)binding)->glBindFramebuffer(GLconst.FRAMEBUFFER, _bufferHandle[index].Value); + } + + /// + /// Bind the frame buffer object with name frame buffer to the frame buffer target specified by target. + /// Target of this frame buffer should be set manually. + /// + /// The frame buffer target of the binding operation. + /// Index of object to be binded in handle set + public unsafe void Bind(FrameBufferTarget target, int index) + { + ((GLcontext*)binding)->glBindFramebuffer((uint)target, _bufferHandle[index].Value); + } + + protected override void Dispose(bool disposing) + { + throw new NotImplementedException(); + } + } +} diff --git a/�代�/StgSharp/Graphics/GL/GLpack.cs b/�代�/StgSharp/Graphics/GL/GLpack.cs index d79dda56..6c53b268 100644 --- a/�代�/StgSharp/Graphics/GL/GLpack.cs +++ b/�代�/StgSharp/Graphics/GL/GLpack.cs @@ -68,6 +68,18 @@ namespace StgSharp.Graphics api->glBindTexture(type, texture.Value); } + /// + /// Bind a frame buffer to a frame buffer target + /// Same function as glBindFramebuffer. + /// + /// The frame buffer target of the binding operation. + /// The handle of the frame buffer object to bind. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void BindFrameBuffer(FrameBufferTarget target, glHandle handle) + { + api->glBindFramebuffer((uint)target,handle.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void BindVertexArray(glHandle handle) { diff --git a/�代�/StgSharp/Graphics/GL/ShaderEdit/Uniform.cs b/�代�/StgSharp/Graphics/GL/ShaderEdit/Uniform.cs index 2ffbbca4..2804d899 100644 --- a/�代�/StgSharp/Graphics/GL/ShaderEdit/Uniform.cs +++ b/�代�/StgSharp/Graphics/GL/ShaderEdit/Uniform.cs @@ -203,7 +203,7 @@ namespace StgSharp.Graphics public unsafe static void SetValue(Uniform uniform, Matrix44 mat) { Matrix44 temp = mat; - api->glUniformMatrix4fv(uniform.Handle.Value, 16, false, (float*)&mat); + api->glUniformMatrix4fv(uniform.id.Value, 1, false, (float*)&mat); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/�代�/StgSharp/Math/Graphic/Camera.cs b/�代�/StgSharp/Math/Graphic/Camera.cs index c19d851e..6214bcfc 100644 --- a/�代�/StgSharp/Math/Graphic/Camera.cs +++ b/�代�/StgSharp/Math/Graphic/Camera.cs @@ -43,30 +43,31 @@ namespace StgSharp.Graphic public sealed class Camera : IglConvertable { - Uniform[] convertedUniform ; + private Uniform convertedUniform ; - glHandleSet uniformHandle; internal bool _isLookAtAvailable; internal Matrix44 cameraAtt; - internal vec3d cameraCoord; + internal vec3d _target, up, cameraCoord; internal Matrix44 _lookAt; internal Matrix44 _projection; public Camera() { cameraAtt = Matrix44.Unit; - cameraCoord = Vec3d.Unit; + _target = Vec3d.Zero; + up = Vec3d.Zero; + cameraCoord = new vec3d(0,0,1); _isLookAtAvailable = false; _lookAt = Matrix44.Unit; - convertedUniform = new Uniform[2]; + _projection = new Matrix44(); } public Camera(vec3d position, vec3d target, vec3d up) : this() { - SetLookAt(position, target, up); + SetViewDirection(position, target, up); } - public Matrix44 LookAt + public Matrix44 View { get { @@ -74,11 +75,9 @@ namespace StgSharp.Graphic { return _lookAt; } - Matrix44 att = cameraAtt; - att.Colum1 = Linear.Normalize(att.Colum1); - Matrix44 coord = Matrix44.Unit; - coord.Colum3.vec -= cameraCoord.vec; - _lookAt = att.Transpose * coord; + Matrix44 move = Matrix44.Unit; + move.Colum3.vec -= cameraCoord.vec; + _lookAt = cameraAtt.Transpose * move; _isLookAtAvailable = true; return _lookAt; } @@ -102,28 +101,36 @@ namespace StgSharp.Graphic cameraCoord.Y -= distance; } - public void Perspective(Radius fovy, Vec2d size, float zNear, float zFar) + public void SetViewRange(Radius fovRadius, vec2d size, vec2d offset, (float front, float back) dephRange) { - if (fovy == Radius.Zero) - { - fovy = new Radius(0.000001f); - } - if (zFar == zNear) - { - return; - } + float + distance = _target.GetLength(), + near = distance - dephRange.front, + far = distance + dephRange.back, + offsetX = offset.X, + offsetY = offset.Y, + width = Scaler.Abs(GeometryScaler.Tan(fovRadius / 2) * near *2), + height = width * size.Y / size.X; - float rad = fovy._radius; - float aspect = size.X / size.Y; - float tanHalfFovy = Scaler.Tan(rad / 2.0f); - tanHalfFovy = tanHalfFovy==float.PositiveInfinity? float.MaxValue : tanHalfFovy; - tanHalfFovy = tanHalfFovy == float.NegativeInfinity ? float.MinValue : tanHalfFovy; + _projection.Colum0.X = 2 * near / width; + _projection.Colum1.Y = 2 * near / height; + _projection.Colum2.X = 2 * offsetX / width; + _projection.Colum2.Y = 2 * offsetY / height; + _projection.Colum2.Z = (far + near) / (near - far); + _projection.Colum2.W = -1; + _projection.Colum3.Z = 2 * near * far / (near - far); - _projection.Colum0.X = 1.0f / (aspect * tanHalfFovy); - _projection.Colum1.Y = 1.0f / tanHalfFovy; - _projection.Colum2.Z = (-(zFar + zNear)) / (zFar - zNear); - _projection.Colum3.W = -1.0f; - _projection.Colum2.Y = (-(2.0f * zFar * zNear)) / (zFar - zNear); + } + + public void Test(params vec4d[] vec) + { + Console.WriteLine(View); + Console.WriteLine(Projection); + Console.WriteLine(Projection * View); + foreach (var item in vec) + { + Console.Write($"{Projection * View * item};"); + } } public void Pitch(Radius r) @@ -142,27 +149,42 @@ namespace StgSharp.Graphic cameraAtt.Colum2.vec = partialCoord.colum1.vec; } - public void SetLookAt(vec3d position, vec3d target, vec3d up) + public void SetViewDirection(vec3d position, vec3d target, vec3d up) { - vec3d direction = target - position; + vec3d direction = position - target; + if (position == cameraCoord && this.up == up && cameraAtt.Colum2.vec == direction.vec) + { + //no difference with precious value + return; + } + if (direction.GetLength() == 0) + { + //deadlock + throw new ArgumentException(); + } + if (Vec3d.IsParallel(direction, up)) + { + throw new ArgumentException(); + } + _target = direction; + cameraCoord = position; + this.up = up; + + _isLookAtAvailable = false; Linear.Normalize(ref direction, ref up); - vec3d right = Linear.Cross(up, direction); - cameraAtt.Colum0.vec = direction.vec; + vec3d right = Linear.Normalize(Linear.Cross(up,direction)); + + cameraAtt.Colum0.vec = right.vec; cameraAtt.Colum1.vec = up.vec; - cameraAtt.Colum2.vec = right.vec; + cameraAtt.Colum2.vec = direction.vec; + } public void DisplayGLtypeDefinition() { - Console.WriteLine( - $"struct camera\n" + - "\t{{\n" + - "\tmatrix4x4 Perspective;\n" + - "\tmatrix4x4 View;\n" + - "\t}}\n" - ); + Console.WriteLine("uniform matrix4x4 cameraName;"); } /// @@ -176,48 +198,11 @@ namespace StgSharp.Graphic /// public unsafe void GainAllUniforms(ShaderProgram source, params string[] uniformName) { - GLcontext* gl = GL.api; - uniformHandle = new glHandleSet(2); - byte[] name1; - byte[] name2; - Console.WriteLine(uniformName.Length); - switch (uniformName.Length) + if (uniformName.Length!=1) { - case 2: - name1 = Encoding.UTF8.GetBytes(uniformName[0]); - name2 = Encoding.UTF8.GetBytes(uniformName[1]); - fixed (byte* namePtr = name1) - { - uniformHandle[(uint)0].Value = gl->glGetUniformLocation( - source.handle.Value, namePtr); - } - fixed (byte* namePtr = name2) - { - uniformHandle[(uint)1].Value = gl->glGetUniformLocation( - source.handle.Value, namePtr); - } - convertedUniform[0] = Uniform.FromHandle(uniformHandle[(uint)0]); - convertedUniform[1] = Uniform.FromHandle(uniformHandle[(uint)1]); - break; - case 1: - name1 = Encoding.UTF8.GetBytes($"{uniformName[0]}.Perspective"); - name2 = Encoding.UTF8.GetBytes($"{uniformName[0]}.View"); - fixed (byte* namePtr = name1) - { - uniformHandle[(uint)0].Value = gl->glGetUniformLocation( - source.handle.Value, namePtr); - } - fixed (byte* namePtr = name2) - { - uniformHandle[(uint)1].Value = gl->glGetUniformLocation( - source.handle.Value, namePtr); - } - convertedUniform[0] = Uniform.FromHandle(uniformHandle[(uint)0]); - convertedUniform[1] = Uniform.FromHandle(uniformHandle[(uint)1]); - break; - default: - throw new ArgumentException(); + throw new ArgumentException(); } + convertedUniform = source.GetUniform(uniformName[0]); } ShaderStruct IglConvertable.GetConvertedGLtype() @@ -227,16 +212,11 @@ namespace StgSharp.Graphic public unsafe void SetAllUniforms() { - GL.SetValue(convertedUniform[0], _projection); - GL.SetValue(convertedUniform[1], LookAt); + GL.SetValue(convertedUniform, Projection * View); } ~Camera() { - if (uniformHandle != null) - { - uniformHandle.Release(); - } } } diff --git a/�代�/StgSharp/Math/Linear/Matrix24.cs b/�代�/StgSharp/Math/Linear/Matrix24.cs index b7dce672..0b9ab0ea 100644 --- a/�代�/StgSharp/Math/Linear/Matrix24.cs +++ b/�代�/StgSharp/Math/Linear/Matrix24.cs @@ -44,10 +44,10 @@ namespace StgSharp.Math [FieldOffset(0)] internal Mat4 mat; [FieldOffset(4 * 4 * sizeof(float))] internal Mat2 transpose; - [FieldOffset(0)] public Vec2d Colum0; - [FieldOffset(16)] public Vec2d Colum1; - [FieldOffset(32)] public Vec2d Colum2; - [FieldOffset(48)] public Vec2d Colum3; + [FieldOffset(0)] public vec2d Colum0; + [FieldOffset(16)] public vec2d Colum1; + [FieldOffset(32)] public vec2d Colum2; + [FieldOffset(48)] public vec2d Colum3; internal Matrix24( Vector4 c0, diff --git a/�代�/StgSharp/Math/Linear/Matrix32.cs b/�代�/StgSharp/Math/Linear/Matrix32.cs index 78429b1d..4c3a1640 100644 --- a/�代�/StgSharp/Math/Linear/Matrix32.cs +++ b/�代�/StgSharp/Math/Linear/Matrix32.cs @@ -114,7 +114,7 @@ namespace StgSharp.Math } } - public vec3d VerticalVecMultiply(Vec2d vec) + public vec3d VerticalVecMultiply(vec2d vec) { return (colum0 * vec.X) + (colum1 * vec.Y); } diff --git a/�代�/StgSharp/Math/Linear/Matrix44.cs b/�代�/StgSharp/Math/Linear/Matrix44.cs index d7558340..05c4f484 100644 --- a/�代�/StgSharp/Math/Linear/Matrix44.cs +++ b/�代�/StgSharp/Math/Linear/Matrix44.cs @@ -42,7 +42,7 @@ namespace StgSharp.Math [StructLayout(LayoutKind.Explicit, Size = (2 * 16 * sizeof(float)) + sizeof(bool), Pack = 16)] - public unsafe struct Matrix44 : IEquatable + public unsafe struct Matrix44 : IEquatable, IMat { [FieldOffset(2 * 64 * sizeof(float))] internal bool isTransposed; @@ -152,6 +152,36 @@ namespace StgSharp.Math 0, 0, 0, 1 ); + public static Matrix44 XNegativeUnit + => new Matrix44( + -1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + public static Matrix44 YNegativeUnit + => new Matrix44( + 1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ); + + public static Matrix44 ZNegativeUnit + => new Matrix44( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1 + ); + public static Matrix44 WNegativeUnit + => new Matrix44( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, -1 + ); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe float Det() { @@ -295,7 +325,6 @@ namespace StgSharp.Math Vector4.Dot(left.transpose.colum3, right.mat.colum1), Vector4.Dot(left.transpose.colum3, right.mat.colum2), Vector4.Dot(left.transpose.colum3, right.mat.colum3) - ); } diff --git a/�代�/StgSharp/Math/Linear/Vector.Cross.cs b/�代�/StgSharp/Math/Linear/Vector.Cross.cs index 673f19ea..e337fe8d 100644 --- a/�代�/StgSharp/Math/Linear/Vector.Cross.cs +++ b/�代�/StgSharp/Math/Linear/Vector.Cross.cs @@ -33,7 +33,7 @@ namespace StgSharp.Math public static unsafe partial class Linear { - public static float Cross(Vec2d vec1, Vec2d vec2) + public static float Cross(vec2d vec1, vec2d vec2) { return (vec1.X * vec2.Y) - (vec1.Y * vec2.X); } diff --git a/�代�/StgSharp/Math/Linear/Vector.GetAngle.cs b/�代�/StgSharp/Math/Linear/Vector.GetAngle.cs index aec170ef..c135e3cb 100644 --- a/�代�/StgSharp/Math/Linear/Vector.GetAngle.cs +++ b/�代�/StgSharp/Math/Linear/Vector.GetAngle.cs @@ -33,7 +33,7 @@ namespace StgSharp.Math public static unsafe partial class Linear { - public static float GetAngle(Vec2d vec1, Vec2d vec2) + public static float GetAngle(vec2d vec1, vec2d vec2) { return Scaler.ACos(1 //vec1.multiple(vec2) diff --git a/�代�/StgSharp/Math/Linear/Vector.GetLength.cs b/�代�/StgSharp/Math/Linear/Vector.GetLength.cs index 24a6a72d..e4707b73 100644 --- a/�代�/StgSharp/Math/Linear/Vector.GetLength.cs +++ b/�代�/StgSharp/Math/Linear/Vector.GetLength.cs @@ -35,19 +35,12 @@ namespace StgSharp.Math public static float GetLength(this vec3d vec) { - return Scaler.Sqrt( - (vec.X * vec.X) + - (vec.Y * vec.Y) + - (vec.Z * vec.Z) - ); + return Scaler.Sqrt(vec.Dot(vec)); } - public static float GetLength(this Vec2d vec) + public static float GetLength(this vec2d vec) { - return Scaler.Sqrt( - (vec.X * vec.X) + - (vec.Y * vec.Y) - ); + return Scaler.Sqrt(vec.Dot(vec)); } } diff --git a/�代�/StgSharp/Math/Linear/Vector.Normalize.cs b/�代�/StgSharp/Math/Linear/Vector.Normalize.cs index 2f72fd22..03b57233 100644 --- a/�代�/StgSharp/Math/Linear/Vector.Normalize.cs +++ b/�代�/StgSharp/Math/Linear/Vector.Normalize.cs @@ -43,18 +43,16 @@ namespace StgSharp.Math public static unsafe void Normalize(ref vec3d source, ref vec3d target) { - Vector4 s = source.vec; - Vector4 t = target.vec; - - s = Vector4.Normalize(s); - - float dotProduct = Vector4.Dot(s, t); - Vector4 projection = Vector4.Multiply(s, t); + Vector3 s = source.v; + Vector3 t = target.v; + s = Vector3.Normalize(s); + Vector3 projection = Vector3.Dot(t, s) / Vector3.Dot(s, s) * s; t -= projection; + t = Vector3.Normalize(t); - source.vec = s; - target.vec = t; + source.v = s; + target.v = t; } public static vec4d Normalize(vec4d vec) diff --git a/�代�/StgSharp/Math/Linear/Vector.VectorTransform.cs b/�代�/StgSharp/Math/Linear/Vector.VectorTransform.cs index e3ed939f..779f22c8 100644 --- a/�代�/StgSharp/Math/Linear/Vector.VectorTransform.cs +++ b/�代�/StgSharp/Math/Linear/Vector.VectorTransform.cs @@ -36,25 +36,25 @@ namespace StgSharp.Math public static unsafe partial class VectorCalc { - public static Vec2d To2D(vec3d vec, CordinatePlain plain) + public static vec2d To2D(vec3d vec, CordinatePlain plain) { switch (plain) { case CordinatePlain.XY: - return new Vec2d(vec.X, vec.Y); + return new vec2d(vec.X, vec.Y); break; case CordinatePlain.YZ: - return new Vec2d(vec.Y, vec.Z); + return new vec2d(vec.Y, vec.Z); break; case CordinatePlain.XZ: - return new Vec2d(vec.X, vec.Z); + return new vec2d(vec.X, vec.Z); break; default: - return default(Vec2d); + return default(vec2d); break; } } - public static vec3d To3D(Vec2d vec) + public static vec3d To3D(vec2d vec) { return new vec3d(vec.X, vec.Y, 0.0f); } diff --git a/�代�/StgSharp/Math/Linear/vec2d.cs b/�代�/StgSharp/Math/Linear/vec2d.cs index 1a6d4dc5..b17ce813 100644 --- a/�代�/StgSharp/Math/Linear/vec2d.cs +++ b/�代�/StgSharp/Math/Linear/vec2d.cs @@ -39,7 +39,7 @@ namespace StgSharp.Math /// Vec2Ds in StgSharp are defaultly usaed as colum vector. /// [StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)] - public struct Vec2d + public struct vec2d { [FieldOffset(0)] @@ -55,56 +55,74 @@ namespace StgSharp.Math [FieldOffset(4)] public float Y; - internal Vec2d(Vector2 vec) + internal vec2d(Vector2 vec) { v = vec; } - public Vec2d(float x, float y) + public vec2d(float x, float y) { v = new Vector2(x, y); } - public static Vec2d Unit => new Vec2d(1, 1); - public static Vec2d Zero => new Vec2d(0, 0); - - public float Cross(Vec2d right) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Cross(vec2d right) { return (X * right.Y) - (Y * right.X); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vec2d operator -(Vec2d left, Vec2d right) + public float Dot(vec2d vec) { - return new Vec2d(left.v - right.v); + return Vector2.Dot(v, vec.v); } - public static bool operator !=(Vec2d left, Vec2d right) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static vec2d operator -(vec2d left, vec2d right) + { + return new vec2d(left.v - right.v); + } + + public static bool operator !=(vec2d left, vec2d right) { return !(left == right); } - public static Vec2d operator *(Vec2d vec, float value) + public static vec2d operator *(vec2d vec, float value) { - return new Vec2d(vec.v * value); + return new vec2d(vec.v * value); } - public static Vec2d operator /(Vec2d vec, float value) + public static vec2d operator /(vec2d vec, float value) { - return new Vec2d(vec.v / value); + return new vec2d(vec.v / value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vec2d operator +(Vec2d left, Vec2d right) + public static vec2d operator +(vec2d left, vec2d right) { - return new Vec2d(left.v + right.v); + return new vec2d(left.v + right.v); } - public static bool operator ==(Vec2d left, Vec2d right) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(vec2d left, vec2d right) { return left.v == right.v; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator vec2d((float, float) tuple) + { + return new vec2d(tuple.Item1, tuple.Item2); + } + } + + public static class Vec2d + { + + public static vec2d Unit => new vec2d(1, 1); + + public static vec2d Zero => new vec2d(0, 0); } } diff --git a/�代�/StgSharp/Math/Linear/vec3d.cs b/�代�/StgSharp/Math/Linear/vec3d.cs index ae762b27..9775bae6 100644 --- a/�代�/StgSharp/Math/Linear/vec3d.cs +++ b/�代�/StgSharp/Math/Linear/vec3d.cs @@ -88,10 +88,7 @@ namespace StgSharp.Math [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Dot(vec3d right) { - Vector4 vector4 = this.vec * right.vec; - return vector4.X - + vector4.Y - + vector4.Z; + return Vector3.Dot(v,right.v); } public bool Equals(vec3d other) @@ -200,8 +197,23 @@ namespace StgSharp.Math public static class Vec3d { - public static vec3d Unit => new vec3d(1, 1, 1); + public static bool IsParallel(vec3d left, vec3d right) + { + return Cross(left,right) == Zero; + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static vec3d Cross(vec3d left, vec3d right) + { + return Linear.Cross(left, right); + } + + public static vec3d One => new vec3d(1, 1, 1); public static vec3d Zero => new vec3d(0, 0, 0); + public static vec3d UnitZ => new vec3d(0, 0, 1); + public static vec3d UnitX => new vec3d(1, 0, 0); + public static vec3d UnitY => new vec3d(0, 1, 0); } } diff --git a/�代�/StgSharp/Math/Linear/vec4d.cs b/�代�/StgSharp/Math/Linear/vec4d.cs index dab8cdfe..7e572307 100644 --- a/�代�/StgSharp/Math/Linear/vec4d.cs +++ b/�代�/StgSharp/Math/Linear/vec4d.cs @@ -34,6 +34,7 @@ using StgSharp.Math; using System; using System.Data.Common; using System.Numerics; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace StgSharp.Math @@ -58,6 +59,11 @@ namespace StgSharp.Math [FieldOffset(8)] public float Z; [FieldOffset(12)] public float W; + public override string ToString() + { + return vec.ToString(); + } + public vec4d(float x, float y, float z, float w) { vec = new Vector4(x, y, z, w); @@ -68,5 +74,17 @@ namespace StgSharp.Math return vec.reg; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static vec4d operator *(Matrix44 mat, vec4d vec) + { + mat.InternalTranspose(); + return new vec4d( + Vector4.Dot( mat.transpose.colum0,vec.vec), + Vector4.Dot( mat.transpose.colum1, vec.vec), + Vector4.Dot( mat.transpose.colum2, vec.vec), + Vector4.Dot( mat.transpose.colum3, vec.vec) + ); + } + } } \ No newline at end of file diff --git a/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.dll b/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.dll index 85053ed3..731ea064 100644 Binary files a/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.dll and b/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.dll differ diff --git a/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.xml b/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.xml index 13be4ca9..e3a0fa47 100644 --- a/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.xml +++ b/�代�/StgSharp/bin/x64/Debug/netstandard2.1/StgSharp.xml @@ -64,12 +64,12 @@ Set all necessary metadata to current form instance - + Resize the current form - A (width,height) representing the new size of current form + A (width,height) representing the new size of current form @@ -79,15 +79,15 @@ New width of the window New height of the window - + Set the size limit of current form - Minimun size of current form. In form of a of (width,height) + Minimun size of current form. In form of a of (width,height) - Maximum size of current form. In form of a of (width,height) + Maximum size of current form. In form of a of (width,height) @@ -412,7 +412,7 @@ An IEEE-754 double precision floating-point value, clamped to the range [0,1]. - + A two dimension vector defined by two elements. Vec2Ds in StgSharp are defaultly usaed as colum vector. diff --git a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.deps.json b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.deps.json index 78a86d98..94d9af4b 100644 --- a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.deps.json +++ b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.deps.json @@ -9,21 +9,13 @@ ".NETStandard,Version=v2.1/": { "StgSharp/1.0.0": { "dependencies": { - "Microsoft.Bcl.HashCode": "1.1.1", - "Microsoft.CSharp": "4.7.0" + "Microsoft.CSharp": "4.7.0", + "Microsoft.Windows.CsWin32": "0.3.49-beta" }, "runtime": { "StgSharp.dll": {} } }, - "Microsoft.Bcl.HashCode/1.1.1": { - "runtime": { - "lib/netstandard2.1/Microsoft.Bcl.HashCode.dll": { - "assemblyVersion": "1.0.0.0", - "fileVersion": "4.700.20.56604" - } - } - }, "Microsoft.CSharp/4.7.0": { "runtime": { "lib/netstandard2.0/Microsoft.CSharp.dll": { @@ -31,6 +23,59 @@ "fileVersion": "4.700.19.56404" } } + }, + "Microsoft.Windows.CsWin32/0.3.49-beta": { + "dependencies": { + "Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha", + "Microsoft.Windows.SDK.Win32Metadata": "55.0.45-preview", + "Microsoft.Windows.WDK.Win32Metadata": "0.9.9-experimental", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.Windows.SDK.Win32Docs/0.1.42-alpha": {}, + "Microsoft.Windows.SDK.Win32Metadata/55.0.45-preview": {}, + "Microsoft.Windows.WDK.Win32Metadata/0.9.9-experimental": { + "dependencies": { + "Microsoft.Windows.SDK.Win32Metadata": "55.0.45-preview" + } + }, + "System.Buffers/4.5.1": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.3.0", + "fileVersion": "4.6.28619.1" + } + } + }, + "System.Memory/4.5.5": { + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.2", + "fileVersion": "4.6.31308.1" + } + } + }, + "System.Numerics.Vectors/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.3.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/6.0.0": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "6.0.0.0", + "fileVersion": "6.0.21.52210" + } + } } } }, @@ -40,19 +85,68 @@ "serviceable": false, "sha512": "" }, - "Microsoft.Bcl.HashCode/1.1.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==", - "path": "microsoft.bcl.hashcode/1.1.1", - "hashPath": "microsoft.bcl.hashcode.1.1.1.nupkg.sha512" - }, "Microsoft.CSharp/4.7.0": { "type": "package", "serviceable": true, "sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==", "path": "microsoft.csharp/4.7.0", "hashPath": "microsoft.csharp.4.7.0.nupkg.sha512" + }, + "Microsoft.Windows.CsWin32/0.3.49-beta": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/iAXplVDKESFyLz/MShuVYVx62YFvFePpq3qrzREl8KScQqG6Z2kV7r9UJTjQS1g+hfy3V+e4m1x9lsu24YNSg==", + "path": "microsoft.windows.cswin32/0.3.49-beta", + "hashPath": "microsoft.windows.cswin32.0.3.49-beta.nupkg.sha512" + }, + "Microsoft.Windows.SDK.Win32Docs/0.1.42-alpha": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA==", + "path": "microsoft.windows.sdk.win32docs/0.1.42-alpha", + "hashPath": "microsoft.windows.sdk.win32docs.0.1.42-alpha.nupkg.sha512" + }, + "Microsoft.Windows.SDK.Win32Metadata/55.0.45-preview": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2i1kVIk8rMuMCYtoeYeWbmCRLqNgb63Berac3Gv+J/pjp0oucopasKgLQNslryhsgBl4xex9ENhJX2MXEW5vdA==", + "path": "microsoft.windows.sdk.win32metadata/55.0.45-preview", + "hashPath": "microsoft.windows.sdk.win32metadata.55.0.45-preview.nupkg.sha512" + }, + "Microsoft.Windows.WDK.Win32Metadata/0.9.9-experimental": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cncPlxLqR25mFOuvpxZPgXgJqRmXyV5eTULj/9w8AQvO/c1xJDEapohRsWkYaia7hCR/EwEzBHr7RU9u93T03w==", + "path": "microsoft.windows.wdk.win32metadata/0.9.9-experimental", + "hashPath": "microsoft.windows.wdk.win32metadata.0.9.9-experimental.nupkg.sha512" + }, + "System.Buffers/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "path": "system.buffers/4.5.1", + "hashPath": "system.buffers.4.5.1.nupkg.sha512" + }, + "System.Memory/4.5.5": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "path": "system.memory/4.5.5", + "hashPath": "system.memory.4.5.5.nupkg.sha512" + }, + "System.Numerics.Vectors/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==", + "path": "system.numerics.vectors/4.4.0", + "hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/6.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==", + "path": "system.runtime.compilerservices.unsafe/6.0.0", + "hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512" } } } \ No newline at end of file diff --git a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.dll b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.dll index 8ea4f7c7..3f496187 100644 Binary files a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.dll and b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.dll differ diff --git a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.xml b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.xml index 8dc7b3b8..13be4ca9 100644 --- a/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.xml +++ b/�代�/StgSharp/bin/x64/RealDebug/netstandard2.1/StgSharp.xml @@ -4,13 +4,7 @@ StgSharp - - - Add a pool to timeline controller, and return the instance of the pool. - - - - + Get the status of a certain key on the keyboard. @@ -22,25 +16,61 @@ Function handler to load an opengl function by serching its name. - the name of the Opengl function + the name of the Opengl function An intptr value representing the pointer to the function - + + + + + + Height of this form, represent in - + - Constructor of a Form, creats an instance of a form and - initilize all the customizing operations. + Width of this form, represent in + + + + + Width of this form, represent in + + + + + Necessary operation to init graphic elements this form. + + OpenGL library binded to current form. + + + + Behaviour of current form when in a frame cycle. - + Init an OpenGl context if current form has not been binded to any context. and set the context binded to + current form as current OpenGL context. - + + Something goes wrong and StgSharp fails in creating a new OpenGL context. + + + + + Set all necessary metadata to current form instance + + + + + Resize the current form + + + A (width,height) representing the new size of current form + @@ -49,23 +79,6 @@ New width of the window New height of the window - - - Resize the current form - - - A (width,height) representing the new size of current form - - - - - Set the size limit of current form - - Minimum width of current form - Minimum height of current form - Maximum width of curent form - Maximum height of current form - Set the size limit of current form @@ -77,205 +90,174 @@ Maximum size of current form. In form of a of (width,height) - + - + Set the size limit of current form - - - + Minimum width of current form + Minimum height of current form + Maximum width of current form + Maximum height of current form - + - + Init this form and render it on screen, and respond with operation - + - + Create a set of . - - - - - - - Call apiClearColor in OpenGL - specifies the red, green, blue, and alpha values used by apiClear to clear the color buffers. - Values specified by apiClearColor are clamped to the range [0,1] - - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - - - - Bind the indexed buffer object to certain type of buffer - - - - - - - Clear buffers to preset values - - - - - - Conpile the provided shader code in string form. - - A string represent the shader's code - An enum represent the type of the shader to - conpile, including vertex shader and fragment shader. - An uint value as the only mark of conpiled shader - - - - Creates a form and its associated - - Required width - Required width - Tittle of the window - - - The instance of created form - - - - - sets the framebuffer resize callback of the specified , - which is called when the framebuffer of the specified is resized. - - The only signiture stands for the to be controlled - Method hadler - - - - Set how a shader parameter read data from a VBO. - - Serial number of the parameter - Amount of data each elements contains - Type of data read by shader - - Pixels stride of each sets of data - - - - - Set data value to a float , - all types of parameters are float. - - The target - The value to be set - - - - Set data value to a int , - all types of parameters are int. - - The target - The value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - The third value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - The third value to be set - The forth value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - A packing four parameters of the uniform - - - - Set data value to a float , - all types of parameters are . - - The target - A value of the uniform - - - - Create an instance of program - - New instance of instance. - - - - A value represent this shader. - - - - - Inti a shader with no program attached. - - - - - Compile the vertex shader to be attached to this shader. - - GLSL code of vertex shader. - - - - Compile the fragment shader to be attached to this shader. - - GLSL code of fragment shader. - - - - Link the shader to current context. - - - - - Get a uniform form current shader, - the value type of the uniform should be provided. - - + Amount of EBO to be created. - + - Let the current context use this shader. + Create a sets of + + Amount of textures to be crated. + + + + + Create a set of . + + Amount of VAO to be crated. + + + + + Create aset of . + + Amount of Object to be created. + + + + + Create an instance of program + + New instance of instance. + + + + Mark that a method in a + should be called when rendering. - + + + Priority level of a render activity. + + + + + One level higher than . + + + + + Two level higher than . + + + + + Three level higher than . + + + + + One level lower than . + + + + + Two level lower than . + + + + + Three level lower than . + + + + + Highest priority, in , it is . + + + + + Default priority, usually is in this priority. + + + + + Lowest priority, in , it is . + + + + + Interface of all kinds OpenGL buffer objects + + + + + Get the only handle to one of the Object instance + + + + + + + Bind a buffer instance to OpenGL + + Index of handle of the object in this instance to be bind + + + + + + + A collecion of handle to Element Buffer Object in OpenGL. + Each value indexed from instance of this class this + is the only handle to one Element Buffer Object. + + + + + + + + + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + Data to write in + How OpenGL use these data, defined by + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + A array of data to write in + How OpenGL use these data, defined by + + + + + + + Load all aupportable OpenGL APIs and bind them to given context. The used as current OpenGL context - A delegate that can get o + A delegate to get address of OprnGL api @@ -284,9 +266,98 @@ Name of the OpenGL api The funtion pointer of the api in form of - + - Tick counter count the frames passed since the program start. + A handle to an OpenGL object, + must be indexed from a . + Direct call will cause + + + + + A handle to an OpenGL object. + + + + + Release all resource in this handle. + This will release all resource in this . + This will be not usable. + + + + + + + + + + + + + + + + + + + + + + + + + + Attach one shader code to a shader program. + + Shader program to attach + Index of shader code in current shader code set. + + + + Init a program with no shader attached. + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Link the shader to current context. + + + + + Let the current context use this shader. @@ -309,6 +380,104 @@ Y position of an enemy entity + + + Init an instance of OpenGL program, + This method should be called before any other StgSharp api. + + + + + Version of current StgSharp platform. + Main version represent in hundred's digit, + and sub version represent in ten's digit. + + + + + Write a log message to log file, and mark the level of this message. + + A string contains information of how current evironment runs. + The severity of current message. + + + + OpenGL numeric type. + An IEEE-754 floating-point value, clamped to the range [0,1]. + + + + + OpenGL numeric type. + An IEEE-754 double precision floating-point value, clamped to the range [0,1]. + + + + + A two dimension vector defined by two elements. + Vec2Ds in StgSharp are defaultly usaed as colum vector. + + + + + Reurns the value of ArcSin(x) + + The sine value of the angle + + + + + + Get the value of E ^ x; + + + + + + + + + + + Returns the value of ln(x). + + + + + calculate the value of x^y + + + + Returns the value of x^y + + + + returns a random float number between 0 and 1. + + + + + + + + + + + + Generates a random seed in int value. + + + + + + Part of a circle. All points on a arc has the same distance to their center. + + + + + A collection of all point on the same plain and has the same distance to a point + + The origin of this coordinate. @@ -338,7 +507,24 @@ The game tick represent time passed by A 3d vector representing movement - + + + Move begin side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + + Move end side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + Move the third vertix. this is a useless method for Parallelograms. @@ -346,7 +532,7 @@ Geometry overdefined - + Move the third vertix. This method is useless for Parallelograms. @@ -359,6 +545,23 @@ 平�几何体。包�三角形,对称四边形,自由多边形等。最多�由16个点�数定义。 + + + Tick time this geometry eas crested + + + + + Get all sides of this . + + A array contains all straight s of current geometry item. + + + + Get a flat cincide with current geometry. + + + Update the coordinate of the point. If this is a moving point, @@ -379,61 +582,1284 @@ A square - + - Add an item to the tail of linked list. + A linear data structure with dynamic length. + It contains a of , + each is twice longer than the former one. - The item ready to add to the list + - + - A two dimension vector defined by two elements. - Vec2Ds in StgSharp are defaultly usaed as colum vector. + Init a with a certain amount of elements prepared. + + Amount of elements to be prepared. + + + + Create a new instance of , + and fill the begining ones of elemtns as given instance. + + Amount of beginning elements to be filled + + + + + Length of this - + - Reurns the value of ArcSin(x) + A pair of value - The sine value of the angle - + + + + The first value. + + + + + The second value. + + + + + A value. + The lower byte is , + and higher byte is . + + + + + A microsecond-accuracy timer. It will refresh every a certain time span. + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Create a new and define the length of time span. + Length of a single time span is defined in seconds. + + + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Time source provider provided in internal framework. + + + + + The method this will call every time a new time span started. + + + + + Get all uniform related to this . + + Shader program requires this camera. + + Name of all related uniforms. + If you fallow form from + - - - Get the value of E ^ x; - - - + + The COLORREF value is used to specify an RGB color. + + When specifying an explicit [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) color, the **COLORREF** value has the following hexadecimal form: `0x00bbggrr` The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. The high-order byte must be zero. The maximum value for a single byte is 0xFF. To create a **COLORREF** color value, use the [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) macro. To extract the individual values for the red, green, and blue components of a color value, use the [**GetRValue**](/windows/desktop/api/Wingdi/nf-wingdi-getrvalue), [GetGValue](/windows/desktop/api/Wingdi/nf-wingdi-getgvalue), and [GetBValue](/windows/desktop/api/Wingdi/nf-wingdi-getbvalue) macros, respectively. + Read more on docs.microsoft.com. + - + - + A pointer to a null-terminated, constant, ANSI character string. - + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, decoding as UTF-8. + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + + A pointer to a null-terminated, constant character string. + + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, up to the first null character (exclusive). + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners. + The RECT structure is identical to the RECTL structure. + + + Specifies the x-coordinate of the upper-left corner of the rectangle. + + + Specifies the y-coordinate of the upper-left corner of the rectangle. + + + Specifies the x-coordinate of the lower-right corner of the rectangle. + + + Specifies the y-coordinate of the lower-right corner of the rectangle. + + + Contains message information from a thread's message queue. + + Learn more about this API from docs.microsoft.com. + + + + + Type: HWND A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message. + Read more on docs.microsoft.com. + + + + + Type: UINT The message identifier. Applications can only use the low word; the high word is reserved by the system. + Read more on docs.microsoft.com. + + + + + Type: WPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: LPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: DWORD The time at which the message was posted. + Read more on docs.microsoft.com. + + + + + Type: POINT The cursor position, in screen coordinates, when the message was posted. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (ANSI) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (Unicode) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + + Represents a Win32 handle that can be closed with . + + + + + Represents a Win32 handle that can be closed with . + + + + The GLYPHMETRICSFLOAT structure contains information about the placement and orientation of a glyph in a character cell. + The values of GLYPHMETRICSFLOAT are specified as notional units. + + + Specifies the width of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the height of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the x and y coordinates of the upper-left corner of the smallest rectangle that completely encloses the glyph. + + + Specifies the horizontal distance from the origin of the current character cell to the origin of the next character cell. + + + Specifies the vertical distance from the origin of the current character cell to the origin of the next character cell. + + + The LAYERPLANEDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice, as documented above, that certain layer plane properties are not supported in the current implementation. The implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers that enhance parts of OpenGL may support some layer plane properties not supported by the generic implementation. + + + Specifies the size of this data structure. Set this value to sizeof(LAYERPLANEDESCRIPTOR). + + + Specifies the version of this data structure. Set this value to 1. + + + + A set of bit flags that specify properties of the layer plane. The properties are generally not mutually exclusive; any combination of bit flags can be set, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + + + + Not used. Must be zero. + + + When the LPD_TRANSPARENT flag is set, specifies the transparent color or index value. Typically the value is zero. + + + The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice carefully, as documented above, that certain pixel format properties are not supported in the current generic implementation. The generic implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers may enhance parts of OpenGL, and may support some pixel format properties not supported by the generic implementation. + + + Specifies the size of this data structure. This value should be set to sizeof(PIXELFORMATDESCRIPTOR). + + + Specifies the version of this data structure. This value should be set to 1. + + + + A set of bit flags that specify properties of the pixel buffer. The properties are generally not mutually exclusive; you can set any combination of bit flags, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + Specifies the number of overlay and underlay planes. Bits 0 through 3 specify up to 15 overlay planes and bits 4 through 7 specify up to 15 underlay planes. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + Specifies the transparent color or index of an underlay plane. When the pixel type is RGBA, dwVisibleMask is a transparent RGB color value. When the pixel type is color index, it is a transparent index value. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + The POINTFLOAT structure contains the x and y coordinates of a point. + + Learn more about this API from docs.microsoft.com. + + + + Specifies the horizontal (x) coordinate of a point. + + + Specifies the vertical (y) coordinate of a point. + + + + Contains extern methods from "GDI32.dll". + + + Contains extern methods from "KERNEL32.dll". + + + Contains extern methods from "OPENGL32.dll". + + + Contains extern methods from "USER32.dll". + + + + The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the specified handle is no longer valid. + A handle to a logical pen, brush, font, bitmap, region, or palette. - Returns the value of ln(x). + If the function succeeds, the return value is nonzero. If the specified handle is not valid or is currently selected into a DC, the return value is zero. + + Do not delete a drawing object (pen or brush) while it is still selected into a DC. When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently. + Read more on docs.microsoft.com. + - - - calculate the value of x^y - - - - Returns the value of x^y + + - - - returns a random float number between 0 and 1. - - + + The ChoosePixelFormat function attempts to match an appropriate pixel format supported by a device context to a given pixel format specification. + Specifies the device context that the function examines to determine the best match for the pixel format descriptor pointed to by ppfd. + + Pointer to a PIXELFORMATDESCRIPTOR structure that specifies the requested pixel format. In this context, the members of the PIXELFORMATDESCRIPTOR structure that ppfd points to are used as follows: + This doc was truncated. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a pixel format index (one-based) that is the closest match to the given pixel format descriptor. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + You must ensure that the pixel format matched by the ChoosePixelFormat function satisfies your requirements. For example, if you request a pixel format with a 24-bit RGB color buffer but the device context offers only 8-bit RGB color buffers, the function returns a pixel format with an 8-bit RGB color buffer. - + + The DescribePixelFormat function obtains information about the pixel format identified by iPixelFormat of the device associated with hdc. The function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd with that pixel format data. + Specifies the device context. + Index that specifies the pixel format. The pixel formats that a device context supports are identified by positive one-based integer indexes. + The size, in bytes, of the structure pointed to by ppfd. The DescribePixelFormat function stores no more than nBytes bytes of data to that structure. Set this value to sizeof(PIXELFORMATDESCRIPTOR). + Pointer to a PIXELFORMATDESCRIPTOR structure whose members the function sets with pixel format data. The function stores the number of bytes copied to the structure in the structure's nSize member. If, upon entry, ppfd is NULL, the function writes no data to the structure. This is useful when you only want to obtain the maximum pixel format index of a device context. + + If the function succeeds, the return value is the maximum pixel format index of the device context. In addition, the function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd according to the specified pixel format. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + The DeleteEnhMetaFile function deletes an enhanced-format metafile or an enhanced-format metafile handle. + A handle to an enhanced metafile. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + If the hemf parameter identifies an enhanced metafile stored in memory, the DeleteEnhMetaFile function deletes the metafile. If hemf identifies a metafile stored on a disk, the function deletes the metafile handle but does not destroy the actual metafile. An application can retrieve the file by calling the GetEnhMetaFile function. + + + + + + The GetEnhMetaFilePixelFormat function retrieves pixel format information for an enhanced metafile. + Identifies the enhanced metafile. + Specifies the size, in bytes, of the buffer into which the pixel format information is copied. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The metafile uses this structure to record the logical pixel format specification. + + If the function succeeds and finds a pixel format, the return value is the size of the metafile's pixel format. If no pixel format is present, the return value is zero. If an error occurs and the function fails, the return value is GDI_ERROR. To get extended error information, call GetLastError. + + + When an enhanced metafile specifies a pixel format in its ENHMETAHEADER structure and the pixel format fits in the buffer, the pixel format information is copied into ppfd. When cbBuffer is too small to contain the pixel format of the metafile, the pixel format is not copied to the buffer. In either case, the function returns the size of the metafile's pixel format. For information on metafile recording and other operations, see Enhanced Metafile Operations. + Read more on docs.microsoft.com. + + + + The GetPixelFormat function obtains the index of the currently selected pixel format of the specified device context. + Specifies the device context of the currently selected pixel format index returned by the function. + + If the function succeeds, the return value is the currently selected pixel format index of the specified device context. This is a positive, one-based index value. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + + + + The SetPixelFormat function sets the pixel format of the specified device context to the format specified by the iPixelFormat index. + Specifies the device context whose pixel format the function attempts to set. + Index that identifies the pixel format to set. The various pixel formats supported by a device context are identified by one-based indexes. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The system's metafile component uses this structure to record the logical pixel format specification. The structure has no other effect upon the behavior of the SetPixelFormat function. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If hdc references a window, calling the SetPixelFormat function also changes the pixel format of the window. Setting the pixel format of a window more than once can lead to significant complications for the Window Manager and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a window's pixel format is set, it cannot be changed. You should select a pixel format in the device context before calling the wglCreateContext function. The wglCreateContext function creates a rendering context for drawing on the device in the selected pixel format of the device context. An OpenGL window has its own pixel format. Because of this, only device contexts retrieved for the client area of an OpenGL window are allowed to draw into the window. As a result, an OpenGL window should be created with the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles. Additionally, the window class attribute should not include the CS_PARENTDC style. + Read more on docs.microsoft.com. + + + + The SwapBuffers function exchanges the front and back buffers if the current pixel format for the window referenced by the specified device context includes a back buffer. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If the current pixel format for the window referenced by the device context does not include a back buffer, this call has no effect and the content of the back buffer is undefined when the function returns. With multithread applications, flush the drawing commands in any other threads drawing to the same window before calling SwapBuffers. + Read more on docs.microsoft.com. + + + + Closes an open object handle. + A valid handle to an open object. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle returned by the FindFirstFile function instead of calling the FindClose function. + + + The CloseHandle function closes handles to the following objects: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. + + A handle to the loaded library module. The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call the GetLastError function. + + + The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file. The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process. It is not safe to call FreeLibrary from DllMain. For more information, see the Remarks section in DllMain. Calling FreeLibrary does not affect other processes that are using the same module. Use caution when calling FreeLibrary with a handle returned by GetModuleHandle. The GetModuleHandle function does not increment a module's reference count, so passing this handle to FreeLibrary can cause a module to be unloaded prematurely. A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur. For details, see the Remarks section of FreeLibraryAndExitThread. + Read more on docs.microsoft.com. + + + + + + + Retrieves a module handle for the specified module. The module must have been loaded by the calling process. (Unicode) + + The name of the loaded module (either a .dll or .exe file). If the file name extension is omitted, the default library extension .dll is appended. The file name string can include a trailing point character (.) to indicate that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process. + If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file). The GetModuleHandle function does not retrieve handles for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the specified module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The returned handle is not global or inheritable. It cannot be duplicated or used by another process. If lpModuleName does not include a path and there is more than one loaded module with the same base name and extension, you cannot predict which module handle will be returned. To work around this problem, you could specify a path, use side-by-side assemblies, or use GetModuleHandleEx to specify a memory location rather than a DLL name. The GetModuleHandle function returns a handle to a mapped module without incrementing its reference count. However, if this handle is passed to the FreeLibrary function, the reference count of the mapped module will be decremented. Therefore, do not pass a handle returned by GetModuleHandle to the FreeLibrary function. Doing so can cause a DLL module to be unmapped prematurely. This function must be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used. For example, suppose that a thread retrieves a module handle, but before it uses the handle, a second thread frees the module. If the system loads another module, it could reuse the module handle that was recently freed. Therefore, the first thread would have a handle to a different module than the one intended. + Read more on docs.microsoft.com. + + + + + + + Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). + + A handle to the DLL module that contains the function or variable. The LoadLibrary, LoadLibraryEx, LoadPackagedLibrary, or GetModuleHandle function returns this handle. The GetProcAddress function does not retrieve addresses from modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero. + + If the function succeeds, the return value is the address of the exported function or variable. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The spelling and case of a function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.def) file. The exported names of functions may differ from the names you use when calling these functions in your code. This difference is hidden by macros used in the SDK header files. For more information, see Conventions for Function Prototypes. The lpProcName parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the .def file. The function then uses the ordinal as an index to read the function's address from a function table. If the .def file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress returns an invalid, non-NULL address, even though there is no function with the specified ordinal. If the function might not exist in the DLL module—for example, if the function is available only on Windows Vista but the application might be running on Windows XP—specify the function by name rather than by ordinal value and design your application to handle the case when the function is not available, as shown in the following code fragment. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Loads the specified module into the address space of the calling process. (LoadLibraryW) + + The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). If the specified module is an executable module, static imports are not loaded; instead, the module is loaded as if by LoadLibraryEx with the `DONT_RESOLVE_DLL_REFERENCES` flag. The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file. If the string specifies a full path, the function searches only that path for the module. If the string specifies a relative path or a module name without a path, the function uses a standard search strategy to find the module; for more information, see the Remarks. If the function cannot find the module, the function fails. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). For more information about paths, see Naming a File or Directory. If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension ".DLL" to the module name. To prevent the function from appending ".DLL" to the module name, include a trailing point character (.) in the module name string. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function. LoadLibrary can be used to load a library module into the address space of the process and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to load other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource or LoadResource. However, do not use LoadLibrary to run an .exe file. Instead, use the CreateProcess function. If the specified module is a DLL that is not already loaded for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If DllMain returns TRUE, LoadLibrary returns a handle to the module. If DllMain returns FALSE, the system unloads the DLL from the process address space and LoadLibrary returns NULL. It is not safe to call LoadLibrary from DllMain. For more information, see the Remarks section in DllMain. Module handles are not global or inheritable. A call to LoadLibrary by one process does not produce a handle that another process can use — for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress. If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first. If no file name extension is specified in the lpFileName parameter, the default library extension .dll is appended. However, the file name string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file. The first directory searched is the directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable. If a relative path is specified, the entire relative path is appended to every token in the DLL search path list. To load a module from a relative path without searching any other path, use GetFullPathName to get a nonrelative path and call LoadLibrary with the nonrelative path. For more information on the DLL search order, see Dynamic-Link Library Search Order. The search path can be altered using the SetDllDirectory function. This solution is recommended instead of using SetCurrentDirectory or hard-coding the full path to the DLL. If a path is specified and there is a redirection file for the application, the function searches for the module in the application's directory. If the module exists in the application's directory, LoadLibrary ignores the specified path and loads the module from the application's directory. If the module does not exist in the application's directory, LoadLibrary loads the module from the specified directory. For more information, see Dynamic Link Library Redirection. If you call LoadLibrary with the name of an assembly without a path specification and the assembly is listed in the system compatible manifest, the call is automatically redirected to the side-by-side assembly. The system maintains a per-process reference count on all loaded modules. Calling LoadLibrary increments the reference count. Calling the FreeLibrary or FreeLibraryAndExitThread function decrements the reference count. The system unloads a module when its reference count reaches zero or when the process terminates (regardless of the reference count). Windows Server 2003 and Windows XP:  The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary on versions of Windows prior to Windows Vista. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). For an example, see Using Thread Local Storage in a Dynamic Link Library.

Security Remarks

Do not use the SearchPath function to retrieve a path to a DLL for a subsequent LoadLibrary call. The SearchPath function uses a different search order than LoadLibrary and it does not use safe process search mode unless this is explicitly enabled by calling SetSearchPathMode with BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Therefore, SearchPath is likely to first search the user’s current working directory for the specified DLL. If an attacker has copied a malicious version of a DLL into the current working directory, the path retrieved by SearchPath will point to the malicious DLL, which LoadLibrary will then load. Do not make assumptions about the operating system version based on a LoadLibrary call that searches for a DLL. If the application is running in an environment where the DLL is legitimately not present but a malicious version of the DLL is in the search path, the malicious version of the DLL may be loaded. Instead, use the recommended techniques described in Getting the System Version.
+ Read more on docs.microsoft.com. +
+
+ + + + + The wglGetProcAddress function returns the address of an OpenGL extension function for use with the current OpenGL rendering context. + + When the function succeeds, the return value is the address of the extension function. When no current rendering context exists or the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The OpenGL library supports multiple implementations of its functions. Extension functions supported in one rendering context are not necessarily available in a separate rendering context. Thus, for a given rendering context in an application, use the function addresses returned by the wglGetProcAddress function only. The spelling and the case of the extension function pointed to by lpszProc must be identical to that of a function supported and implemented by OpenGL. Because extension functions are not exported by OpenGL, you must use wglGetProcAddress to get the addresses of vendor-specific extension functions. The extension function addresses are unique for each pixel format. All rendering contexts of a given pixel format share the same extension function addresses. + Read more on docs.microsoft.com. + + + + The wglDeleteContext function deletes a specified OpenGL rendering context. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + It is an error to delete an OpenGL rendering context that is the current context of another thread. However, if a rendering context is the calling thread's current context, the wglDeleteContext function changes the rendering context to being not current before deleting it. The wglDeleteContext function does not delete the device context associated with the OpenGL rendering context when you call the wglMakeCurrent function. After calling wglDeleteContext, you must call DeleteDC to delete the associated device context. + Read more on docs.microsoft.com. + + + + + + + The wglCreateContext function creates a new OpenGL rendering context, which is suitable for drawing on the device referenced by hdc. The rendering context has the same pixel format as the device context. + + If the function succeeds, the return value is a valid handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is not the same as a device context. Set the pixel format of the device context before creating a rendering context. For more information on setting the device context's pixel format, see the SetPixelFormat function. To use OpenGL, you create a rendering context, select it as a thread's current rendering context, and then call OpenGL functions. When you are finished with the rendering context, you dispose of it by calling the wglDeleteContext function. The following code example shows wglCreateContext usage. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglCreateLayerContext function creates a new OpenGL rendering context for drawing to a specified layer plane on a device context. + + If the function succeeds, the return value is a handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is a port through which all OpenGL commands pass. Every thread that makes OpenGL calls must have one current, active rendering context. A rendering context is not the same as a device context; a rendering context contains information specific to OpenGL, while a device context contains information specific to GDI. Before you create a rendering context, set the pixel format of the device context with the SetPixelFormat function. You can use a rendering context in a specified layer plane of a window with identical pixel formats only. With OpenGL applications that use multiple threads, you create a rendering context, select it as the current rendering context of a thread, and make OpenGL calls for the specified thread. When you are finished with the rendering context of the thread, call the wglDeleteContext function. + Read more on docs.microsoft.com. + + + + + + + The wglCopyContext function copies selected groups of rendering states from one OpenGL rendering context to another. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + Using the wglCopyContext function, you can synchronize the rendering state of two rendering contexts. You can only copy the rendering state between two rendering contexts within the same process. The rendering contexts must be from the same OpenGL implementation. For example, you can always copy a rendering state between two rendering contexts with identical pixel format in the same process. You can copy the same state information available only with the glPushAttrib function. You cannot copy some state information, such as pixel pack/unpack state, render mode state, select state, and feedback state. When you call wglCopyContext, make sure that the destination rendering context, hglrcDst, is not current to any thread. + Read more on docs.microsoft.com. + + + + + + + The wglDescribeLayerPlane function obtains information about the layer planes of a given pixel format. + + If the function succeeds, the return value is TRUE. In addition, the wglDescribeLayerPlane function sets the members of the LAYERPLANEDESCRIPTOR structure pointed to by plpd according to the specified layer plane (iLayerPlane ) of the specified pixel format (iPixelFormat ). If the function fails, the return value is FALSE. + + The numbering of planes (iLayerPlane ) determines their order. Higher-numbered planes overlay lower-numbered planes. + + + + + + The wglGetCurrentContext function obtains a handle to the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, wglGetCurrentContext returns a handle to that rendering context. Otherwise, the return value is NULL. + The current OpenGL rendering context of a thread is associated with a device context by means of the wglMakeCurrent function. You can use the wglGetCurrentDC function to obtain a handle to the device context associated with the current OpenGL rendering context. + + + The wglGetCurrentDC function obtains a handle to the device context that is associated with the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, the function returns a handle to the device context associated with that rendering context by means of the wglMakeCurrent function. Otherwise, the return value is NULL. + You associate a device context with an OpenGL rendering context when it calls the wglMakeCurrent function. You can use the wglGetCurrentContext function to obtain a handle to the calling thread's current OpenGL rendering context. + + + + + + Retrieves the palette entries from a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or when no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index layer plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. + Read more on docs.microsoft.com. + + + + + + + The wglMakeCurrent function makes a specified OpenGL rendering context the calling thread's current rendering context. + When the wglMakeCurrent function succeeds, the return value is TRUE; otherwise the return value is FALSE. To get extended error information, call GetLastError. + + The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format. GDI transformation and clipping in hdc are not supported by the rendering context. The current rendering context uses the hdc device context until the rendering context is no longer current. Before switching to the new rendering context, OpenGL flushes any previous rendering context that was current to the calling thread. A thread can have one current rendering context. A process can have multiple rendering contexts by means of multithreading. A thread must set a current rendering context before calling any OpenGL functions. Otherwise, all OpenGL calls are ignored. A rendering context can be current to only one thread at a time. You cannot make a rendering context current to multiple threads. An application can perform multithread drawing by making different rendering contexts current to different threads, supplying each thread with its own rendering context and device context. If an error occurs, the wglMakeCurrent function makes the thread's current rendering context not current before returning. + Read more on docs.microsoft.com. + + + + The wglRealizeLayerPalette function maps palette entries from a given color-index layer plane into the physical palette or initializes the palette of an RGBA layer plane. + If the function succeeds, the return value is TRUE, even if bRealize is TRUE and the physical palette is not available. If the function fails or when no pixel format is selected, the return value is FALSE. To get extended error information, call GetLastError. + + The physical palette for a layer plane is a shared resource among windows with layer planes. When more than one window attempts to realize a palette for a given physical layer plane, only one palette at a time is realized. When you call the wglRealizeLayerPalette function, the layer palette of a foreground window is always realized first. When a window's layer palette is realized, its palette entries are always mapped one-to-one into the physical palette. Unlike GDI logical palettes, with wglRealizeLayerPalette there is no mapping of other windows' layer palettes to the current physical palette. Whenever a window becomes the foreground window, call wglRealizeLayerPalette to realize its layer palettes again, even if the pixel type of the layer plane is RGBA. Because wglRealizeLayerPalette doesn't realize the palette of the main plane, use GDI palette functions to realize the main plane palette. + Read more on docs.microsoft.com. + + + + + + + Sets the palette entries in a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. The wglSetLayerPaletteEntries function doesn't set the palette entries of the main plane palette. To update the main plane palette, use GDI palette functions. + Read more on docs.microsoft.com. + + + + + + + The wglShareLists function enables multiple OpenGL rendering contexts to share a single display-list space. + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and the display lists are not shared. To get extended error information, call GetLastError. + + + When you create an OpenGL rendering context, it has its own display-list space. The wglShareLists function enables a rendering context to share the display-list space of another rendering context; any number of rendering contexts can share a single display-list space. Once a rendering context shares a display-list space, the rendering context always uses the display-list space until the rendering context is deleted. When the last rendering context of a shared display-list space is deleted, the shared display-list space is deleted. All the indexes and definitions of display lists in a shared display-list space are shared. You can only share display lists with rendering contexts within the same process. However, not all rendering contexts in a process can share display lists. Rendering contexts can share display lists only if they use the same implementation of OpenGL functions. All client rendering contexts of a given pixel format can always share display lists. All rendering contexts of a shared display list must use an identical pixel format. Otherwise the results depend on the implementation of OpenGL used.
Note  The wglShareLists function is only available with OpenGL version 1.01 or later. To determine the version number of the implementation of OpenGL, call glGetString.
 
+ Read more on docs.microsoft.com. +
+
+ + The wglSwapLayerBuffers function swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + When a layer plane doesn't include a back buffer, calling the wglSwapLayerBuffers function has no effect on that layer plane. After you call wglSwapLayerBuffers, the state of the back buffer content is given in the corresponding LAYERPLANEDESCRIPTOR structure of the layer plane or in the PIXELFORMATDESCRIPTOR structure of the main plane. The wglSwapLayerBuffers function swaps the front and back buffers in the specified layer planes simultaneously. Some devices don't support swapping layer planes individually; they swap all layer planes as a group. When the PFD_SWAP_LAYER_BUFFERS flag of the PIXELFORMATDESCRIPTOR structure is set, it indicates that a device can swap individual layer planes and that you can call wglSwapLayerBuffers. With applications that use multiple threads, before calling wglSwapLayerBuffers, clear all drawing commands in all threads drawing to the same window. + Read more on docs.microsoft.com. + + + + The wglUseFontBitmaps function creates a set of bitmap display lists for use in the current OpenGL rendering context. (Unicode) + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + The wglUseFontBitmaps function defines count display lists in the current OpenGL rendering context. Each display list has an identifying number, starting at listBase. Each display list consists of a single call to glBitmap. The definition of bitmap listBase + i is taken from the glyph first + i of the font currently selected in the device context specified by hdc. If a glyph is not defined, then the function defines an empty display list for it. The wglUseFontBitmaps function creates bitmap text in the plane of the screen. It enables the labeling of objects in OpenGL. In the current version of Microsoft's implementation of OpenGL, you cannot make GDI calls to a device context that has a double-buffered pixel format. Therefore, you cannot use the GDI fonts and text functions with such device contexts. You can use the wglUseFontBitmaps function to circumvent this limitation and draw text in a double-buffered device context. The function determines the parameters of each call to glBitmap as follows. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglUseFontOutlines function creates a set of display lists, one for each glyph of the currently selected outline font of a device context, for use with the current rendering context. (Unicode) + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and no display lists are generated. To get extended error information, call GetLastError. + + + The wglUseFontOutlines function defines the glyphs of an outline font with display lists in the current rendering context. The wglUseFontOutlines function works with TrueType fonts only; stroke and raster fonts are not supported. Each display list consists of either line segments or polygons, and has a unique identifying number starting with the listBase number. The wglUseFontOutlines function approximates glyph outlines by subdividing the quadratic B-spline curves of the outline into line segments, until the distance between the outline and the interpolated midpoint is within the value specified by deviation. This is the final format used when format is WGL_FONT_LINES. When you specify WGL_FONT_OUTLINES, the display lists created don't contain any normals; thus lighting doesn't work properly. To get the correct lighting of lines use WGL_FONT_POLYGONS and set glPolygonMode( GL_FRONT, GL_LINE ). When you specify format as WGL_FONT_POLYGONS the outlines are further tessellated into separate triangles, triangle fans, triangle strips, or quadrilateral strips to create the surface of each glyph. With WGL_FONT_POLYGONS, the created display lists call glFrontFace( GL_CW ) or glFrontFace( GL_CCW ); thus the current front-face value might be altered. For the best appearance of text with WGL_FONT_POLYGONS, cull the back faces as follows: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys an icon and frees any memory the icon occupied. + + Type: HICON A handle to the icon to be destroyed. The icon must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + It is only necessary to call DestroyIcon for icons and cursors created with the following functions: CreateIconFromResourceEx (if called without the LR_SHARED flag), CreateIconIndirect, and CopyIcon. Do not use this function to destroy a shared icon. A shared icon is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared icon. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys a cursor and frees any memory the cursor occupied. Do not use this function to destroy a shared cursor. + + Type: HCURSOR A handle to the cursor to be destroyed. The cursor must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + The DestroyCursor function destroys a nonshared cursor. Do not use this function to destroy a shared cursor. A shared cursor is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared cursor: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Calculates the required size of the window rectangle, based on the desired client-rectangle size. The window rectangle can then be passed to the CreateWindow function to create a window whose client area is the desired size. + + Type: LPRECT A pointer to a RECT structure that contains the coordinates of the top-left and bottom-right corners of the desired client area. When the function returns, the structure contains the coordinates of the top-left and bottom-right corners of the window to accommodate the desired client area. + Read more on docs.microsoft.com. + + + Type: DWORD The window style of the window whose required size is to be calculated. Note that you cannot specify the WS_OVERLAPPED style. + Read more on docs.microsoft.com. + + + Type: BOOL Indicates whether the window has a menu. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A client rectangle is the smallest rectangle that completely encloses a client area. A window rectangle is the smallest rectangle that completely encloses the window, which includes the client area and the nonclient area. The AdjustWindowRect function does not add extra space when a menu bar wraps to two or more rows. The AdjustWindowRect function does not take the WS_VSCROLL or WS_HSCROLL styles into account. To account for the scroll bars, call the GetSystemMetrics function with SM_CXVSCROLL or SM_CYHSCROLL. + Read more on docs.microsoft.com. + + + + Destroys the specified menu and frees any memory that the menu occupies. + + Type: HMENU A handle to the menu to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Before closing, an application must use the DestroyMenu function to destroy a menu not assigned to a window. A menu that is assigned to a window is automatically destroyed when the application closes. DestroyMenu is recursive, that is, it will destroy the menu and all its submenus. + Read more on docs.microsoft.com. + + + + + + + Creates an overlapped, pop-up, or child window with an extended window style; otherwise, this function is identical to the CreateWindow function. (Unicode) + + Type: DWORD The extended window style of the window being created. For a list of possible values, see Extended Window Styles. + Read more on docs.microsoft.com. + + + Type: LPCTSTR A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax "#num". + Read more on docs.microsoft.com. + + + Type: DWORD The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section. + Read more on docs.microsoft.com. + + + Type: int The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If x is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero. + Read more on docs.microsoft.com. + + + Type: int The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area. + If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter. + Read more on docs.microsoft.com. + + + Type: int The width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinates to the right edge of the screen; the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameter are set to zero. + Read more on docs.microsoft.com. + + + Type: int The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows. To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window. + Read more on docs.microsoft.com. + + + Type: HMENU A handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window. + Read more on docs.microsoft.com. + + + Type: HINSTANCE A handle to the instance of the module to be associated with the window. + Read more on docs.microsoft.com. + + + Type: LPVOID Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns. If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed. + Read more on docs.microsoft.com. + + + Type: HWND If the function succeeds, the return value is a handle to the new window. If the function fails, the return value is NULL. To get extended error information, call GetLastError. This function typically fails for one of the following reasons: + This doc was truncated. + + + The CreateWindowEx function sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created. If the created window is a child window, its default position is at the bottom of the Z-order. If the created window is a top-level window, its default position is at the top of the Z-order (but beneath all topmost windows unless the created window is itself topmost). For information on controlling whether the Taskbar displays a button for the created window, see Managing Taskbar Buttons. For information on removing a window, see the DestroyWindow function. The following predefined control classes can be specified in the lpClassName parameter. Note the corresponding control styles you can use in the dwStyle parameter. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Calls the default window procedure to provide default processing for any window messages that an application does not process. (Unicode) + + Type: HWND A handle to the window procedure that received the message. + Read more on docs.microsoft.com. + + + Type: UINT The message. + Read more on docs.microsoft.com. + + + Type: WPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value is the result of the message processing and depends on the message. + + + > [!NOTE] > The winuser.h header defines DefWindowProc as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + Destroys the specified window. + + Type: HWND A handle to the window to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A thread cannot use DestroyWindow to destroy a window created by a different thread. If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style, a WM_PARENTNOTIFY message is sent to the parent. + Read more on docs.microsoft.com. + + + + + + + Dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function. (DispatchMessageW) + + Type: const MSG* A pointer to a structure that contains the message. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored. + + + The MSG structure must contain valid message values. If the lpmsg parameter points to a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The GetDC function retrieves a handle to a device context (DC) for the client area of a specified window or for the entire screen. + A handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen. + + If the function succeeds, the return value is a handle to the DC for the specified window's client area. If the function fails, the return value is NULL. + + + The GetDC function retrieves a common, class, or private DC depending on the class style of the specified window. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. However, for common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For example, the default font is System, which is a bitmap font. Because of this, the handle to a common DC returned by GetDC does not tell you what font, color, or brush was used when the window was drawn. To determine the font, call GetTextFace. Note that the handle to the DC can only be used by a single thread at any one time. After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. ReleaseDC must be called from the same thread that called GetDC. The number of DCs is limited only by available memory. + Read more on docs.microsoft.com. + + + + + + + Loads the specified cursor resource from the executable (.EXE) file associated with an application instance. (Unicode) + + Type: HINSTANCE A handle to an instance of the module whose executable file contains the cursor to be loaded. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The name of the cursor resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can also be used to create this value. To use one of the predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the following values. + This doc was truncated. + Read more on docs.microsoft.com. + + + Type: HCURSOR If the function succeeds, the return value is the handle to the newly loaded cursor. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The LoadCursor function loads the cursor resource only if it has not been loaded; otherwise, it retrieves the handle to the existing resource. This function returns a valid cursor handle only if the lpCursorName parameter is a pointer to a cursor resource. If lpCursorName is a pointer to any type of resource other than a cursor (such as an icon), the return value is not NULL, even though it is not a valid cursor handle. The LoadCursor function searches the cursor resource most appropriate for the cursor for the current display device. The cursor resource can be a color or monochrome bitmap.

DPI Virtualization

This API does not participate in DPI virtualization. The output returned is not affected by the DPI of the calling thread.
+ Read more on docs.microsoft.com. +
+
+ + + + + Dispatches incoming nonqueued messages, checks the thread message queue for a posted message, and retrieves the message (if any exist). (Unicode) + + Type: LPMSG A pointer to an MSG structure that receives message information. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the window whose messages are to be retrieved. The window must belong to the current thread. + If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed. If hWnd is -1, PeekMessage retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage. + Read more on docs.microsoft.com. + + + Type: UINT The value of the first message in the range of messages to be examined. Use WM_KEYFIRST (0x0100) to specify the first keyboard message or WM_MOUSEFIRST (0x0200) to specify the first mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + + Type: UINT The value of the last message in the range of messages to be examined. Use WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to specify the last mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + Type: UINT + + Type: BOOL If a message is available, the return value is nonzero. If no messages are available, the return value is zero. + + + PeekMessage retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax parameters; the high word is reserved for the system. Note that PeekMessage always retrieves WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax. During this call, the system dispatches (DispatchMessage) pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events. If no filter is specified, messages are processed in the following order: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. + + Type: int The application exit code. This value is used as the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future. When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + + Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. (RegisterClassW) + + Type: const WNDCLASS* A pointer to a WNDCLASS structure. You must fill the structure with the appropriate class attributes before passing it to the function. + Read more on docs.microsoft.com. + + + Type: ATOM If the function succeeds, the return value is a class atom that uniquely identifies the class being registered. This atom can only be used by the CreateWindow, CreateWindowEx, GetClassInfo, GetClassInfoEx, FindWindow, FindWindowEx, and UnregisterClass functions and the IActiveIMMap::FilterClientWindows method. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + If you register the window class by using RegisterClassA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterClassW, the application requests that the system pass text parameters of messages as Unicode. The IsWindowUnicode function enables applications to query the nature of each window. For more information on ANSI and Unicode functions, see Conventions for Function Prototypes. All window classes that an application registers are unregistered when it terminates. No window classes registered by a DLL are unregistered when the DLL is unloaded. A DLL must explicitly unregister its classes when it is unloaded. + Read more on docs.microsoft.com. + + + + The ReleaseDC function releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs. + A handle to the window whose DC is to be released. + A handle to the DC to be released. + + The return value indicates whether the DC was released. If the DC was released, the return value is 1. If the DC was not released, the return value is zero. + + + The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC. An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function. ReleaseDC must be called from the same thread that called GetDC. + Read more on docs.microsoft.com. + + + + Sets the specified window's show state. + + Type: HWND A handle to the window. + Read more on docs.microsoft.com. + + Type: int + + Type: BOOL If the window was previously visible, the return value is nonzero. If the window was previously hidden, the return value is zero. + + + To perform certain special effects when showing or hiding a window, use AnimateWindow. The first time an application calls ShowWindow, it should use the WinMain function's nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function's nCmdShow parameter. As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in the structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function. + + Type: const MSG* A pointer to an MSG structure that contains message information retrieved from the calling thread's message queue by using the GetMessage or PeekMessage function. + Read more on docs.microsoft.com. + + + Type: BOOL If the message is translated (that is, a character message is posted to the thread's message queue), the return value is nonzero. If the message is WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP, the return value is nonzero, regardless of the translation. If the message is not translated (that is, a character message is not posted to the thread's message queue), the return value is zero. + + + The TranslateMessage function does not modify the message pointed to by the lpMsg parameter. + WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message. TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver. If applications process virtual-key messages for some other purpose, they should not call TranslateMessage. For instance, an application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. + Handle to the window to be updated. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + + Learn more about this API from docs.microsoft.com. + + + - Generates a random seed in int value. + Represents a Win32 handle that can be closed with . - diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfo.cs b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfo.cs index 5d8e4cc4..065e8866 100644 --- a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfo.cs +++ b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgSharp")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+127fcdbfd32fd1caa4a55ced77c7e738f038a59c")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharp")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharp")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache index ec9228b6..672e9494 100644 --- a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache +++ b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache @@ -1 +1 @@ -5bdfaeb828f7a682fca2531a3fe7bdbf99d72f6a17b3554b2957f0377659471f +2ada11ce10f85a06de358a4bce8f696ee557358f3cc0800e7c9895081adaf694 diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.dll b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.dll index 85053ed3..731ea064 100644 Binary files a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.dll and b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.dll differ diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.sourcelink.json b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.sourcelink.json index 7a2e3d97..3d27e0be 100644 --- a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.sourcelink.json +++ b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.sourcelink.json @@ -1 +1 @@ -{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/127fcdbfd32fd1caa4a55ced77c7e738f038a59c/*"}} \ No newline at end of file +{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1/*"}} \ No newline at end of file diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.xml b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.xml index 13be4ca9..e3a0fa47 100644 --- a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.xml +++ b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/StgSharp.xml @@ -64,12 +64,12 @@ Set all necessary metadata to current form instance
- + Resize the current form - A (width,height) representing the new size of current form + A (width,height) representing the new size of current form @@ -79,15 +79,15 @@ New width of the window New height of the window - + Set the size limit of current form - Minimun size of current form. In form of a of (width,height) + Minimun size of current form. In form of a of (width,height) - Maximum size of current form. In form of a of (width,height) + Maximum size of current form. In form of a of (width,height) @@ -412,7 +412,7 @@ An IEEE-754 double precision floating-point value, clamped to the range [0,1].
- + A two dimension vector defined by two elements. Vec2Ds in StgSharp are defaultly usaed as colum vector. diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/ref/StgSharp.dll b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/ref/StgSharp.dll index 18115c0b..b89a8dc6 100644 Binary files a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/ref/StgSharp.dll and b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/ref/StgSharp.dll differ diff --git a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/refint/StgSharp.dll b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/refint/StgSharp.dll index 18115c0b..b89a8dc6 100644 Binary files a/�代�/StgSharp/obj/x64/Debug/netstandard2.1/refint/StgSharp.dll and b/�代�/StgSharp/obj/x64/Debug/netstandard2.1/refint/StgSharp.dll differ diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfo.cs b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfo.cs index b97c071a..546cfe30 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfo.cs +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgSharp")] [assembly: System.Reflection.AssemblyConfigurationAttribute("RealDebug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharp")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharp")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache index 8d6be633..5a6f068d 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.AssemblyInfoInputs.cache @@ -1 +1 @@ -be8c87457a5494f89505f86881a5a0a81b016a0af5e05652a33e90ae26d1de26 +a4d87f123623c0d54bffb0363e32d6d18ef4e35b2660ec27f7fa02dbef84070a diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.GeneratedMSBuildEditorConfig.editorconfig b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.GeneratedMSBuildEditorConfig.editorconfig index f1c64107..44183f7b 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.GeneratedMSBuildEditorConfig.editorconfig +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.GeneratedMSBuildEditorConfig.editorconfig @@ -1,4 +1,6 @@ is_global = true +build_property.CsWin32InputMetadataPaths = C:\Users\Nitlo\.nuget\packages\microsoft.windows.sdk.win32metadata\55.0.45-preview\Windows.Win32.winmd|C:\Users\Nitlo\.nuget\packages\microsoft.windows.wdk.win32metadata\0.9.9-experimental\Windows.Wdk.winmd +build_property.CsWin32InputDocPaths = C:\Users\Nitlo\.nuget\packages\microsoft.windows.sdk.win32docs\0.1.42-alpha\apidocs.msgpack build_property.TargetFramework = netstandard2.1 build_property.TargetPlatformMinVersion = 7.0 build_property.UsingMicrosoftNETSdkWeb = diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.assets.cache b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.assets.cache index a6cd5153..d5074852 100644 Binary files a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.assets.cache and b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.assets.cache differ diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.AssemblyReference.cache b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.AssemblyReference.cache index d05e3e18..950133b6 100644 Binary files a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.AssemblyReference.cache and b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.AssemblyReference.cache differ diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.CoreCompileInputs.cache b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.CoreCompileInputs.cache index 1b5d57e1..6f0f082d 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.CoreCompileInputs.cache +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -14600979b7047444373c4005ac1629cd56f39a50173cc96850f6c359889fb1d1 +e4e38d06f2245eb242b8b57f041e9aa530a505c39a7af341bfce0c12f0b62443 diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.dll b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.dll index 8ea4f7c7..3f496187 100644 Binary files a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.dll and b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.dll differ diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.sourcelink.json b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.sourcelink.json index 47d8fd92..3d27e0be 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.sourcelink.json +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.sourcelink.json @@ -1 +1 @@ -{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/8148c10acd65bd764d3e12418a1ebd37938d8501/*"}} \ No newline at end of file +{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1/*"}} \ No newline at end of file diff --git a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.xml b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.xml index 8dc7b3b8..13be4ca9 100644 --- a/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.xml +++ b/�代�/StgSharp/obj/x64/RealDebug/netstandard2.1/StgSharp.xml @@ -4,13 +4,7 @@ StgSharp - - - Add a pool to timeline controller, and return the instance of the pool. - - - - + Get the status of a certain key on the keyboard. @@ -22,25 +16,61 @@ Function handler to load an opengl function by serching its name. - the name of the Opengl function + the name of the Opengl function An intptr value representing the pointer to the function - + + + + + + Height of this form, represent in - + - Constructor of a Form, creats an instance of a form and - initilize all the customizing operations. + Width of this form, represent in + + + + + Width of this form, represent in + + + + + Necessary operation to init graphic elements this form. + + OpenGL library binded to current form. + + + + Behaviour of current form when in a frame cycle. - + Init an OpenGl context if current form has not been binded to any context. and set the context binded to + current form as current OpenGL context. - + + Something goes wrong and StgSharp fails in creating a new OpenGL context. + + + + + Set all necessary metadata to current form instance + + + + + Resize the current form + + + A (width,height) representing the new size of current form + @@ -49,23 +79,6 @@ New width of the window New height of the window - - - Resize the current form - - - A (width,height) representing the new size of current form - - - - - Set the size limit of current form - - Minimum width of current form - Minimum height of current form - Maximum width of curent form - Maximum height of current form - Set the size limit of current form @@ -77,205 +90,174 @@ Maximum size of current form. In form of a of (width,height) - + - + Set the size limit of current form - - - + Minimum width of current form + Minimum height of current form + Maximum width of current form + Maximum height of current form - + - + Init this form and render it on screen, and respond with operation - + - + Create a set of . - - - - - - - Call apiClearColor in OpenGL - specifies the red, green, blue, and alpha values used by apiClear to clear the color buffers. - Values specified by apiClearColor are clamped to the range [0,1] - - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - Specify the red values used when the color buffers are cleared. - - - - Bind the indexed buffer object to certain type of buffer - - - - - - - Clear buffers to preset values - - - - - - Conpile the provided shader code in string form. - - A string represent the shader's code - An enum represent the type of the shader to - conpile, including vertex shader and fragment shader. - An uint value as the only mark of conpiled shader - - - - Creates a form and its associated - - Required width - Required width - Tittle of the window - - - The instance of created form - - - - - sets the framebuffer resize callback of the specified , - which is called when the framebuffer of the specified is resized. - - The only signiture stands for the to be controlled - Method hadler - - - - Set how a shader parameter read data from a VBO. - - Serial number of the parameter - Amount of data each elements contains - Type of data read by shader - - Pixels stride of each sets of data - - - - - Set data value to a float , - all types of parameters are float. - - The target - The value to be set - - - - Set data value to a int , - all types of parameters are int. - - The target - The value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - The third value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - The first value to be set - The second value to be set - The third value to be set - The forth value to be set - - - - Set data value to a float , - all types of parameters are float. - - The target - A packing four parameters of the uniform - - - - Set data value to a float , - all types of parameters are . - - The target - A value of the uniform - - - - Create an instance of program - - New instance of instance. - - - - A value represent this shader. - - - - - Inti a shader with no program attached. - - - - - Compile the vertex shader to be attached to this shader. - - GLSL code of vertex shader. - - - - Compile the fragment shader to be attached to this shader. - - GLSL code of fragment shader. - - - - Link the shader to current context. - - - - - Get a uniform form current shader, - the value type of the uniform should be provided. - - + Amount of EBO to be created. - + - Let the current context use this shader. + Create a sets of + + Amount of textures to be crated. + + + + + Create a set of . + + Amount of VAO to be crated. + + + + + Create aset of . + + Amount of Object to be created. + + + + + Create an instance of program + + New instance of instance. + + + + Mark that a method in a + should be called when rendering. - + + + Priority level of a render activity. + + + + + One level higher than . + + + + + Two level higher than . + + + + + Three level higher than . + + + + + One level lower than . + + + + + Two level lower than . + + + + + Three level lower than . + + + + + Highest priority, in , it is . + + + + + Default priority, usually is in this priority. + + + + + Lowest priority, in , it is . + + + + + Interface of all kinds OpenGL buffer objects + + + + + Get the only handle to one of the Object instance + + + + + + + Bind a buffer instance to OpenGL + + Index of handle of the object in this instance to be bind + + + + + + + A collecion of handle to Element Buffer Object in OpenGL. + Each value indexed from instance of this class this + is the only handle to one Element Buffer Object. + + + + + + + + + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + Data to write in + How OpenGL use these data, defined by + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + A array of data to write in + How OpenGL use these data, defined by + + + + + + + Load all aupportable OpenGL APIs and bind them to given context. The used as current OpenGL context - A delegate that can get o + A delegate to get address of OprnGL api @@ -284,9 +266,98 @@ Name of the OpenGL api The funtion pointer of the api in form of - + - Tick counter count the frames passed since the program start. + A handle to an OpenGL object, + must be indexed from a . + Direct call will cause + + + + + A handle to an OpenGL object. + + + + + Release all resource in this handle. + This will release all resource in this . + This will be not usable. + + + + + + + + + + + + + + + + + + + + + + + + + + Attach one shader code to a shader program. + + Shader program to attach + Index of shader code in current shader code set. + + + + Init a program with no shader attached. + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Link the shader to current context. + + + + + Let the current context use this shader. @@ -309,6 +380,104 @@ Y position of an enemy entity + + + Init an instance of OpenGL program, + This method should be called before any other StgSharp api. + + + + + Version of current StgSharp platform. + Main version represent in hundred's digit, + and sub version represent in ten's digit. + + + + + Write a log message to log file, and mark the level of this message. + + A string contains information of how current evironment runs. + The severity of current message. + + + + OpenGL numeric type. + An IEEE-754 floating-point value, clamped to the range [0,1]. + + + + + OpenGL numeric type. + An IEEE-754 double precision floating-point value, clamped to the range [0,1]. + + + + + A two dimension vector defined by two elements. + Vec2Ds in StgSharp are defaultly usaed as colum vector. + + + + + Reurns the value of ArcSin(x) + + The sine value of the angle + + + + + + Get the value of E ^ x; + + + + + + + + + + + Returns the value of ln(x). + + + + + calculate the value of x^y + + + + Returns the value of x^y + + + + returns a random float number between 0 and 1. + + + + + + + + + + + + Generates a random seed in int value. + + + + + + Part of a circle. All points on a arc has the same distance to their center. + + + + + A collection of all point on the same plain and has the same distance to a point + + The origin of this coordinate. @@ -338,7 +507,24 @@ The game tick represent time passed by A 3d vector representing movement - + + + Move begin side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + + Move end side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + Move the third vertix. this is a useless method for Parallelograms. @@ -346,7 +532,7 @@ Geometry overdefined - + Move the third vertix. This method is useless for Parallelograms. @@ -359,6 +545,23 @@ 平�几何体。包�三角形,对称四边形,自由多边形等。最多�由16个点�数定义。 + + + Tick time this geometry eas crested + + + + + Get all sides of this . + + A array contains all straight s of current geometry item. + + + + Get a flat cincide with current geometry. + + + Update the coordinate of the point. If this is a moving point, @@ -379,61 +582,1284 @@ A square - + - Add an item to the tail of linked list. + A linear data structure with dynamic length. + It contains a of , + each is twice longer than the former one. - The item ready to add to the list + - + - A two dimension vector defined by two elements. - Vec2Ds in StgSharp are defaultly usaed as colum vector. + Init a with a certain amount of elements prepared. + + Amount of elements to be prepared. + + + + Create a new instance of , + and fill the begining ones of elemtns as given instance. + + Amount of beginning elements to be filled + + + + + Length of this - + - Reurns the value of ArcSin(x) + A pair of value - The sine value of the angle - + + + + The first value. + + + + + The second value. + + + + + A value. + The lower byte is , + and higher byte is . + + + + + A microsecond-accuracy timer. It will refresh every a certain time span. + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Create a new and define the length of time span. + Length of a single time span is defined in seconds. + + + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Time source provider provided in internal framework. + + + + + The method this will call every time a new time span started. + + + + + Get all uniform related to this . + + Shader program requires this camera. + + Name of all related uniforms. + If you fallow form from + - - - Get the value of E ^ x; - - - + + The COLORREF value is used to specify an RGB color. + + When specifying an explicit [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) color, the **COLORREF** value has the following hexadecimal form: `0x00bbggrr` The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. The high-order byte must be zero. The maximum value for a single byte is 0xFF. To create a **COLORREF** color value, use the [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) macro. To extract the individual values for the red, green, and blue components of a color value, use the [**GetRValue**](/windows/desktop/api/Wingdi/nf-wingdi-getrvalue), [GetGValue](/windows/desktop/api/Wingdi/nf-wingdi-getgvalue), and [GetBValue](/windows/desktop/api/Wingdi/nf-wingdi-getbvalue) macros, respectively. + Read more on docs.microsoft.com. + - + - + A pointer to a null-terminated, constant, ANSI character string. - + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, decoding as UTF-8. + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + + A pointer to a null-terminated, constant character string. + + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, up to the first null character (exclusive). + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners. + The RECT structure is identical to the RECTL structure. + + + Specifies the x-coordinate of the upper-left corner of the rectangle. + + + Specifies the y-coordinate of the upper-left corner of the rectangle. + + + Specifies the x-coordinate of the lower-right corner of the rectangle. + + + Specifies the y-coordinate of the lower-right corner of the rectangle. + + + Contains message information from a thread's message queue. + + Learn more about this API from docs.microsoft.com. + + + + + Type: HWND A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message. + Read more on docs.microsoft.com. + + + + + Type: UINT The message identifier. Applications can only use the low word; the high word is reserved by the system. + Read more on docs.microsoft.com. + + + + + Type: WPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: LPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: DWORD The time at which the message was posted. + Read more on docs.microsoft.com. + + + + + Type: POINT The cursor position, in screen coordinates, when the message was posted. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (ANSI) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (Unicode) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + + Represents a Win32 handle that can be closed with . + + + + + Represents a Win32 handle that can be closed with . + + + + The GLYPHMETRICSFLOAT structure contains information about the placement and orientation of a glyph in a character cell. + The values of GLYPHMETRICSFLOAT are specified as notional units. + + + Specifies the width of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the height of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the x and y coordinates of the upper-left corner of the smallest rectangle that completely encloses the glyph. + + + Specifies the horizontal distance from the origin of the current character cell to the origin of the next character cell. + + + Specifies the vertical distance from the origin of the current character cell to the origin of the next character cell. + + + The LAYERPLANEDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice, as documented above, that certain layer plane properties are not supported in the current implementation. The implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers that enhance parts of OpenGL may support some layer plane properties not supported by the generic implementation. + + + Specifies the size of this data structure. Set this value to sizeof(LAYERPLANEDESCRIPTOR). + + + Specifies the version of this data structure. Set this value to 1. + + + + A set of bit flags that specify properties of the layer plane. The properties are generally not mutually exclusive; any combination of bit flags can be set, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + + + + Not used. Must be zero. + + + When the LPD_TRANSPARENT flag is set, specifies the transparent color or index value. Typically the value is zero. + + + The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice carefully, as documented above, that certain pixel format properties are not supported in the current generic implementation. The generic implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers may enhance parts of OpenGL, and may support some pixel format properties not supported by the generic implementation. + + + Specifies the size of this data structure. This value should be set to sizeof(PIXELFORMATDESCRIPTOR). + + + Specifies the version of this data structure. This value should be set to 1. + + + + A set of bit flags that specify properties of the pixel buffer. The properties are generally not mutually exclusive; you can set any combination of bit flags, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + Specifies the number of overlay and underlay planes. Bits 0 through 3 specify up to 15 overlay planes and bits 4 through 7 specify up to 15 underlay planes. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + Specifies the transparent color or index of an underlay plane. When the pixel type is RGBA, dwVisibleMask is a transparent RGB color value. When the pixel type is color index, it is a transparent index value. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + The POINTFLOAT structure contains the x and y coordinates of a point. + + Learn more about this API from docs.microsoft.com. + + + + Specifies the horizontal (x) coordinate of a point. + + + Specifies the vertical (y) coordinate of a point. + + + + Contains extern methods from "GDI32.dll". + + + Contains extern methods from "KERNEL32.dll". + + + Contains extern methods from "OPENGL32.dll". + + + Contains extern methods from "USER32.dll". + + + + The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the specified handle is no longer valid. + A handle to a logical pen, brush, font, bitmap, region, or palette. - Returns the value of ln(x). + If the function succeeds, the return value is nonzero. If the specified handle is not valid or is currently selected into a DC, the return value is zero. + + Do not delete a drawing object (pen or brush) while it is still selected into a DC. When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently. + Read more on docs.microsoft.com. + - - - calculate the value of x^y - - - - Returns the value of x^y + + - - - returns a random float number between 0 and 1. - - + + The ChoosePixelFormat function attempts to match an appropriate pixel format supported by a device context to a given pixel format specification. + Specifies the device context that the function examines to determine the best match for the pixel format descriptor pointed to by ppfd. + + Pointer to a PIXELFORMATDESCRIPTOR structure that specifies the requested pixel format. In this context, the members of the PIXELFORMATDESCRIPTOR structure that ppfd points to are used as follows: + This doc was truncated. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a pixel format index (one-based) that is the closest match to the given pixel format descriptor. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + You must ensure that the pixel format matched by the ChoosePixelFormat function satisfies your requirements. For example, if you request a pixel format with a 24-bit RGB color buffer but the device context offers only 8-bit RGB color buffers, the function returns a pixel format with an 8-bit RGB color buffer. - + + The DescribePixelFormat function obtains information about the pixel format identified by iPixelFormat of the device associated with hdc. The function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd with that pixel format data. + Specifies the device context. + Index that specifies the pixel format. The pixel formats that a device context supports are identified by positive one-based integer indexes. + The size, in bytes, of the structure pointed to by ppfd. The DescribePixelFormat function stores no more than nBytes bytes of data to that structure. Set this value to sizeof(PIXELFORMATDESCRIPTOR). + Pointer to a PIXELFORMATDESCRIPTOR structure whose members the function sets with pixel format data. The function stores the number of bytes copied to the structure in the structure's nSize member. If, upon entry, ppfd is NULL, the function writes no data to the structure. This is useful when you only want to obtain the maximum pixel format index of a device context. + + If the function succeeds, the return value is the maximum pixel format index of the device context. In addition, the function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd according to the specified pixel format. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + The DeleteEnhMetaFile function deletes an enhanced-format metafile or an enhanced-format metafile handle. + A handle to an enhanced metafile. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + If the hemf parameter identifies an enhanced metafile stored in memory, the DeleteEnhMetaFile function deletes the metafile. If hemf identifies a metafile stored on a disk, the function deletes the metafile handle but does not destroy the actual metafile. An application can retrieve the file by calling the GetEnhMetaFile function. + + + + + + The GetEnhMetaFilePixelFormat function retrieves pixel format information for an enhanced metafile. + Identifies the enhanced metafile. + Specifies the size, in bytes, of the buffer into which the pixel format information is copied. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The metafile uses this structure to record the logical pixel format specification. + + If the function succeeds and finds a pixel format, the return value is the size of the metafile's pixel format. If no pixel format is present, the return value is zero. If an error occurs and the function fails, the return value is GDI_ERROR. To get extended error information, call GetLastError. + + + When an enhanced metafile specifies a pixel format in its ENHMETAHEADER structure and the pixel format fits in the buffer, the pixel format information is copied into ppfd. When cbBuffer is too small to contain the pixel format of the metafile, the pixel format is not copied to the buffer. In either case, the function returns the size of the metafile's pixel format. For information on metafile recording and other operations, see Enhanced Metafile Operations. + Read more on docs.microsoft.com. + + + + The GetPixelFormat function obtains the index of the currently selected pixel format of the specified device context. + Specifies the device context of the currently selected pixel format index returned by the function. + + If the function succeeds, the return value is the currently selected pixel format index of the specified device context. This is a positive, one-based index value. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + + + + The SetPixelFormat function sets the pixel format of the specified device context to the format specified by the iPixelFormat index. + Specifies the device context whose pixel format the function attempts to set. + Index that identifies the pixel format to set. The various pixel formats supported by a device context are identified by one-based indexes. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The system's metafile component uses this structure to record the logical pixel format specification. The structure has no other effect upon the behavior of the SetPixelFormat function. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If hdc references a window, calling the SetPixelFormat function also changes the pixel format of the window. Setting the pixel format of a window more than once can lead to significant complications for the Window Manager and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a window's pixel format is set, it cannot be changed. You should select a pixel format in the device context before calling the wglCreateContext function. The wglCreateContext function creates a rendering context for drawing on the device in the selected pixel format of the device context. An OpenGL window has its own pixel format. Because of this, only device contexts retrieved for the client area of an OpenGL window are allowed to draw into the window. As a result, an OpenGL window should be created with the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles. Additionally, the window class attribute should not include the CS_PARENTDC style. + Read more on docs.microsoft.com. + + + + The SwapBuffers function exchanges the front and back buffers if the current pixel format for the window referenced by the specified device context includes a back buffer. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If the current pixel format for the window referenced by the device context does not include a back buffer, this call has no effect and the content of the back buffer is undefined when the function returns. With multithread applications, flush the drawing commands in any other threads drawing to the same window before calling SwapBuffers. + Read more on docs.microsoft.com. + + + + Closes an open object handle. + A valid handle to an open object. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle returned by the FindFirstFile function instead of calling the FindClose function. + + + The CloseHandle function closes handles to the following objects: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. + + A handle to the loaded library module. The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call the GetLastError function. + + + The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file. The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process. It is not safe to call FreeLibrary from DllMain. For more information, see the Remarks section in DllMain. Calling FreeLibrary does not affect other processes that are using the same module. Use caution when calling FreeLibrary with a handle returned by GetModuleHandle. The GetModuleHandle function does not increment a module's reference count, so passing this handle to FreeLibrary can cause a module to be unloaded prematurely. A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur. For details, see the Remarks section of FreeLibraryAndExitThread. + Read more on docs.microsoft.com. + + + + + + + Retrieves a module handle for the specified module. The module must have been loaded by the calling process. (Unicode) + + The name of the loaded module (either a .dll or .exe file). If the file name extension is omitted, the default library extension .dll is appended. The file name string can include a trailing point character (.) to indicate that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process. + If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file). The GetModuleHandle function does not retrieve handles for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the specified module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The returned handle is not global or inheritable. It cannot be duplicated or used by another process. If lpModuleName does not include a path and there is more than one loaded module with the same base name and extension, you cannot predict which module handle will be returned. To work around this problem, you could specify a path, use side-by-side assemblies, or use GetModuleHandleEx to specify a memory location rather than a DLL name. The GetModuleHandle function returns a handle to a mapped module without incrementing its reference count. However, if this handle is passed to the FreeLibrary function, the reference count of the mapped module will be decremented. Therefore, do not pass a handle returned by GetModuleHandle to the FreeLibrary function. Doing so can cause a DLL module to be unmapped prematurely. This function must be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used. For example, suppose that a thread retrieves a module handle, but before it uses the handle, a second thread frees the module. If the system loads another module, it could reuse the module handle that was recently freed. Therefore, the first thread would have a handle to a different module than the one intended. + Read more on docs.microsoft.com. + + + + + + + Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). + + A handle to the DLL module that contains the function or variable. The LoadLibrary, LoadLibraryEx, LoadPackagedLibrary, or GetModuleHandle function returns this handle. The GetProcAddress function does not retrieve addresses from modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero. + + If the function succeeds, the return value is the address of the exported function or variable. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The spelling and case of a function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.def) file. The exported names of functions may differ from the names you use when calling these functions in your code. This difference is hidden by macros used in the SDK header files. For more information, see Conventions for Function Prototypes. The lpProcName parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the .def file. The function then uses the ordinal as an index to read the function's address from a function table. If the .def file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress returns an invalid, non-NULL address, even though there is no function with the specified ordinal. If the function might not exist in the DLL module—for example, if the function is available only on Windows Vista but the application might be running on Windows XP—specify the function by name rather than by ordinal value and design your application to handle the case when the function is not available, as shown in the following code fragment. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Loads the specified module into the address space of the calling process. (LoadLibraryW) + + The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). If the specified module is an executable module, static imports are not loaded; instead, the module is loaded as if by LoadLibraryEx with the `DONT_RESOLVE_DLL_REFERENCES` flag. The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file. If the string specifies a full path, the function searches only that path for the module. If the string specifies a relative path or a module name without a path, the function uses a standard search strategy to find the module; for more information, see the Remarks. If the function cannot find the module, the function fails. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). For more information about paths, see Naming a File or Directory. If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension ".DLL" to the module name. To prevent the function from appending ".DLL" to the module name, include a trailing point character (.) in the module name string. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function. LoadLibrary can be used to load a library module into the address space of the process and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to load other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource or LoadResource. However, do not use LoadLibrary to run an .exe file. Instead, use the CreateProcess function. If the specified module is a DLL that is not already loaded for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If DllMain returns TRUE, LoadLibrary returns a handle to the module. If DllMain returns FALSE, the system unloads the DLL from the process address space and LoadLibrary returns NULL. It is not safe to call LoadLibrary from DllMain. For more information, see the Remarks section in DllMain. Module handles are not global or inheritable. A call to LoadLibrary by one process does not produce a handle that another process can use — for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress. If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first. If no file name extension is specified in the lpFileName parameter, the default library extension .dll is appended. However, the file name string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file. The first directory searched is the directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable. If a relative path is specified, the entire relative path is appended to every token in the DLL search path list. To load a module from a relative path without searching any other path, use GetFullPathName to get a nonrelative path and call LoadLibrary with the nonrelative path. For more information on the DLL search order, see Dynamic-Link Library Search Order. The search path can be altered using the SetDllDirectory function. This solution is recommended instead of using SetCurrentDirectory or hard-coding the full path to the DLL. If a path is specified and there is a redirection file for the application, the function searches for the module in the application's directory. If the module exists in the application's directory, LoadLibrary ignores the specified path and loads the module from the application's directory. If the module does not exist in the application's directory, LoadLibrary loads the module from the specified directory. For more information, see Dynamic Link Library Redirection. If you call LoadLibrary with the name of an assembly without a path specification and the assembly is listed in the system compatible manifest, the call is automatically redirected to the side-by-side assembly. The system maintains a per-process reference count on all loaded modules. Calling LoadLibrary increments the reference count. Calling the FreeLibrary or FreeLibraryAndExitThread function decrements the reference count. The system unloads a module when its reference count reaches zero or when the process terminates (regardless of the reference count). Windows Server 2003 and Windows XP:  The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary on versions of Windows prior to Windows Vista. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). For an example, see Using Thread Local Storage in a Dynamic Link Library.

Security Remarks

Do not use the SearchPath function to retrieve a path to a DLL for a subsequent LoadLibrary call. The SearchPath function uses a different search order than LoadLibrary and it does not use safe process search mode unless this is explicitly enabled by calling SetSearchPathMode with BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Therefore, SearchPath is likely to first search the user’s current working directory for the specified DLL. If an attacker has copied a malicious version of a DLL into the current working directory, the path retrieved by SearchPath will point to the malicious DLL, which LoadLibrary will then load. Do not make assumptions about the operating system version based on a LoadLibrary call that searches for a DLL. If the application is running in an environment where the DLL is legitimately not present but a malicious version of the DLL is in the search path, the malicious version of the DLL may be loaded. Instead, use the recommended techniques described in Getting the System Version.
+ Read more on docs.microsoft.com. +
+
+ + + + + The wglGetProcAddress function returns the address of an OpenGL extension function for use with the current OpenGL rendering context. + + When the function succeeds, the return value is the address of the extension function. When no current rendering context exists or the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The OpenGL library supports multiple implementations of its functions. Extension functions supported in one rendering context are not necessarily available in a separate rendering context. Thus, for a given rendering context in an application, use the function addresses returned by the wglGetProcAddress function only. The spelling and the case of the extension function pointed to by lpszProc must be identical to that of a function supported and implemented by OpenGL. Because extension functions are not exported by OpenGL, you must use wglGetProcAddress to get the addresses of vendor-specific extension functions. The extension function addresses are unique for each pixel format. All rendering contexts of a given pixel format share the same extension function addresses. + Read more on docs.microsoft.com. + + + + The wglDeleteContext function deletes a specified OpenGL rendering context. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + It is an error to delete an OpenGL rendering context that is the current context of another thread. However, if a rendering context is the calling thread's current context, the wglDeleteContext function changes the rendering context to being not current before deleting it. The wglDeleteContext function does not delete the device context associated with the OpenGL rendering context when you call the wglMakeCurrent function. After calling wglDeleteContext, you must call DeleteDC to delete the associated device context. + Read more on docs.microsoft.com. + + + + + + + The wglCreateContext function creates a new OpenGL rendering context, which is suitable for drawing on the device referenced by hdc. The rendering context has the same pixel format as the device context. + + If the function succeeds, the return value is a valid handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is not the same as a device context. Set the pixel format of the device context before creating a rendering context. For more information on setting the device context's pixel format, see the SetPixelFormat function. To use OpenGL, you create a rendering context, select it as a thread's current rendering context, and then call OpenGL functions. When you are finished with the rendering context, you dispose of it by calling the wglDeleteContext function. The following code example shows wglCreateContext usage. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglCreateLayerContext function creates a new OpenGL rendering context for drawing to a specified layer plane on a device context. + + If the function succeeds, the return value is a handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is a port through which all OpenGL commands pass. Every thread that makes OpenGL calls must have one current, active rendering context. A rendering context is not the same as a device context; a rendering context contains information specific to OpenGL, while a device context contains information specific to GDI. Before you create a rendering context, set the pixel format of the device context with the SetPixelFormat function. You can use a rendering context in a specified layer plane of a window with identical pixel formats only. With OpenGL applications that use multiple threads, you create a rendering context, select it as the current rendering context of a thread, and make OpenGL calls for the specified thread. When you are finished with the rendering context of the thread, call the wglDeleteContext function. + Read more on docs.microsoft.com. + + + + + + + The wglCopyContext function copies selected groups of rendering states from one OpenGL rendering context to another. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + Using the wglCopyContext function, you can synchronize the rendering state of two rendering contexts. You can only copy the rendering state between two rendering contexts within the same process. The rendering contexts must be from the same OpenGL implementation. For example, you can always copy a rendering state between two rendering contexts with identical pixel format in the same process. You can copy the same state information available only with the glPushAttrib function. You cannot copy some state information, such as pixel pack/unpack state, render mode state, select state, and feedback state. When you call wglCopyContext, make sure that the destination rendering context, hglrcDst, is not current to any thread. + Read more on docs.microsoft.com. + + + + + + + The wglDescribeLayerPlane function obtains information about the layer planes of a given pixel format. + + If the function succeeds, the return value is TRUE. In addition, the wglDescribeLayerPlane function sets the members of the LAYERPLANEDESCRIPTOR structure pointed to by plpd according to the specified layer plane (iLayerPlane ) of the specified pixel format (iPixelFormat ). If the function fails, the return value is FALSE. + + The numbering of planes (iLayerPlane ) determines their order. Higher-numbered planes overlay lower-numbered planes. + + + + + + The wglGetCurrentContext function obtains a handle to the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, wglGetCurrentContext returns a handle to that rendering context. Otherwise, the return value is NULL. + The current OpenGL rendering context of a thread is associated with a device context by means of the wglMakeCurrent function. You can use the wglGetCurrentDC function to obtain a handle to the device context associated with the current OpenGL rendering context. + + + The wglGetCurrentDC function obtains a handle to the device context that is associated with the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, the function returns a handle to the device context associated with that rendering context by means of the wglMakeCurrent function. Otherwise, the return value is NULL. + You associate a device context with an OpenGL rendering context when it calls the wglMakeCurrent function. You can use the wglGetCurrentContext function to obtain a handle to the calling thread's current OpenGL rendering context. + + + + + + Retrieves the palette entries from a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or when no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index layer plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. + Read more on docs.microsoft.com. + + + + + + + The wglMakeCurrent function makes a specified OpenGL rendering context the calling thread's current rendering context. + When the wglMakeCurrent function succeeds, the return value is TRUE; otherwise the return value is FALSE. To get extended error information, call GetLastError. + + The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format. GDI transformation and clipping in hdc are not supported by the rendering context. The current rendering context uses the hdc device context until the rendering context is no longer current. Before switching to the new rendering context, OpenGL flushes any previous rendering context that was current to the calling thread. A thread can have one current rendering context. A process can have multiple rendering contexts by means of multithreading. A thread must set a current rendering context before calling any OpenGL functions. Otherwise, all OpenGL calls are ignored. A rendering context can be current to only one thread at a time. You cannot make a rendering context current to multiple threads. An application can perform multithread drawing by making different rendering contexts current to different threads, supplying each thread with its own rendering context and device context. If an error occurs, the wglMakeCurrent function makes the thread's current rendering context not current before returning. + Read more on docs.microsoft.com. + + + + The wglRealizeLayerPalette function maps palette entries from a given color-index layer plane into the physical palette or initializes the palette of an RGBA layer plane. + If the function succeeds, the return value is TRUE, even if bRealize is TRUE and the physical palette is not available. If the function fails or when no pixel format is selected, the return value is FALSE. To get extended error information, call GetLastError. + + The physical palette for a layer plane is a shared resource among windows with layer planes. When more than one window attempts to realize a palette for a given physical layer plane, only one palette at a time is realized. When you call the wglRealizeLayerPalette function, the layer palette of a foreground window is always realized first. When a window's layer palette is realized, its palette entries are always mapped one-to-one into the physical palette. Unlike GDI logical palettes, with wglRealizeLayerPalette there is no mapping of other windows' layer palettes to the current physical palette. Whenever a window becomes the foreground window, call wglRealizeLayerPalette to realize its layer palettes again, even if the pixel type of the layer plane is RGBA. Because wglRealizeLayerPalette doesn't realize the palette of the main plane, use GDI palette functions to realize the main plane palette. + Read more on docs.microsoft.com. + + + + + + + Sets the palette entries in a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. The wglSetLayerPaletteEntries function doesn't set the palette entries of the main plane palette. To update the main plane palette, use GDI palette functions. + Read more on docs.microsoft.com. + + + + + + + The wglShareLists function enables multiple OpenGL rendering contexts to share a single display-list space. + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and the display lists are not shared. To get extended error information, call GetLastError. + + + When you create an OpenGL rendering context, it has its own display-list space. The wglShareLists function enables a rendering context to share the display-list space of another rendering context; any number of rendering contexts can share a single display-list space. Once a rendering context shares a display-list space, the rendering context always uses the display-list space until the rendering context is deleted. When the last rendering context of a shared display-list space is deleted, the shared display-list space is deleted. All the indexes and definitions of display lists in a shared display-list space are shared. You can only share display lists with rendering contexts within the same process. However, not all rendering contexts in a process can share display lists. Rendering contexts can share display lists only if they use the same implementation of OpenGL functions. All client rendering contexts of a given pixel format can always share display lists. All rendering contexts of a shared display list must use an identical pixel format. Otherwise the results depend on the implementation of OpenGL used.
Note  The wglShareLists function is only available with OpenGL version 1.01 or later. To determine the version number of the implementation of OpenGL, call glGetString.
 
+ Read more on docs.microsoft.com. +
+
+ + The wglSwapLayerBuffers function swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + When a layer plane doesn't include a back buffer, calling the wglSwapLayerBuffers function has no effect on that layer plane. After you call wglSwapLayerBuffers, the state of the back buffer content is given in the corresponding LAYERPLANEDESCRIPTOR structure of the layer plane or in the PIXELFORMATDESCRIPTOR structure of the main plane. The wglSwapLayerBuffers function swaps the front and back buffers in the specified layer planes simultaneously. Some devices don't support swapping layer planes individually; they swap all layer planes as a group. When the PFD_SWAP_LAYER_BUFFERS flag of the PIXELFORMATDESCRIPTOR structure is set, it indicates that a device can swap individual layer planes and that you can call wglSwapLayerBuffers. With applications that use multiple threads, before calling wglSwapLayerBuffers, clear all drawing commands in all threads drawing to the same window. + Read more on docs.microsoft.com. + + + + The wglUseFontBitmaps function creates a set of bitmap display lists for use in the current OpenGL rendering context. (Unicode) + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + The wglUseFontBitmaps function defines count display lists in the current OpenGL rendering context. Each display list has an identifying number, starting at listBase. Each display list consists of a single call to glBitmap. The definition of bitmap listBase + i is taken from the glyph first + i of the font currently selected in the device context specified by hdc. If a glyph is not defined, then the function defines an empty display list for it. The wglUseFontBitmaps function creates bitmap text in the plane of the screen. It enables the labeling of objects in OpenGL. In the current version of Microsoft's implementation of OpenGL, you cannot make GDI calls to a device context that has a double-buffered pixel format. Therefore, you cannot use the GDI fonts and text functions with such device contexts. You can use the wglUseFontBitmaps function to circumvent this limitation and draw text in a double-buffered device context. The function determines the parameters of each call to glBitmap as follows. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglUseFontOutlines function creates a set of display lists, one for each glyph of the currently selected outline font of a device context, for use with the current rendering context. (Unicode) + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and no display lists are generated. To get extended error information, call GetLastError. + + + The wglUseFontOutlines function defines the glyphs of an outline font with display lists in the current rendering context. The wglUseFontOutlines function works with TrueType fonts only; stroke and raster fonts are not supported. Each display list consists of either line segments or polygons, and has a unique identifying number starting with the listBase number. The wglUseFontOutlines function approximates glyph outlines by subdividing the quadratic B-spline curves of the outline into line segments, until the distance between the outline and the interpolated midpoint is within the value specified by deviation. This is the final format used when format is WGL_FONT_LINES. When you specify WGL_FONT_OUTLINES, the display lists created don't contain any normals; thus lighting doesn't work properly. To get the correct lighting of lines use WGL_FONT_POLYGONS and set glPolygonMode( GL_FRONT, GL_LINE ). When you specify format as WGL_FONT_POLYGONS the outlines are further tessellated into separate triangles, triangle fans, triangle strips, or quadrilateral strips to create the surface of each glyph. With WGL_FONT_POLYGONS, the created display lists call glFrontFace( GL_CW ) or glFrontFace( GL_CCW ); thus the current front-face value might be altered. For the best appearance of text with WGL_FONT_POLYGONS, cull the back faces as follows: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys an icon and frees any memory the icon occupied. + + Type: HICON A handle to the icon to be destroyed. The icon must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + It is only necessary to call DestroyIcon for icons and cursors created with the following functions: CreateIconFromResourceEx (if called without the LR_SHARED flag), CreateIconIndirect, and CopyIcon. Do not use this function to destroy a shared icon. A shared icon is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared icon. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys a cursor and frees any memory the cursor occupied. Do not use this function to destroy a shared cursor. + + Type: HCURSOR A handle to the cursor to be destroyed. The cursor must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + The DestroyCursor function destroys a nonshared cursor. Do not use this function to destroy a shared cursor. A shared cursor is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared cursor: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Calculates the required size of the window rectangle, based on the desired client-rectangle size. The window rectangle can then be passed to the CreateWindow function to create a window whose client area is the desired size. + + Type: LPRECT A pointer to a RECT structure that contains the coordinates of the top-left and bottom-right corners of the desired client area. When the function returns, the structure contains the coordinates of the top-left and bottom-right corners of the window to accommodate the desired client area. + Read more on docs.microsoft.com. + + + Type: DWORD The window style of the window whose required size is to be calculated. Note that you cannot specify the WS_OVERLAPPED style. + Read more on docs.microsoft.com. + + + Type: BOOL Indicates whether the window has a menu. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A client rectangle is the smallest rectangle that completely encloses a client area. A window rectangle is the smallest rectangle that completely encloses the window, which includes the client area and the nonclient area. The AdjustWindowRect function does not add extra space when a menu bar wraps to two or more rows. The AdjustWindowRect function does not take the WS_VSCROLL or WS_HSCROLL styles into account. To account for the scroll bars, call the GetSystemMetrics function with SM_CXVSCROLL or SM_CYHSCROLL. + Read more on docs.microsoft.com. + + + + Destroys the specified menu and frees any memory that the menu occupies. + + Type: HMENU A handle to the menu to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Before closing, an application must use the DestroyMenu function to destroy a menu not assigned to a window. A menu that is assigned to a window is automatically destroyed when the application closes. DestroyMenu is recursive, that is, it will destroy the menu and all its submenus. + Read more on docs.microsoft.com. + + + + + + + Creates an overlapped, pop-up, or child window with an extended window style; otherwise, this function is identical to the CreateWindow function. (Unicode) + + Type: DWORD The extended window style of the window being created. For a list of possible values, see Extended Window Styles. + Read more on docs.microsoft.com. + + + Type: LPCTSTR A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax "#num". + Read more on docs.microsoft.com. + + + Type: DWORD The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section. + Read more on docs.microsoft.com. + + + Type: int The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If x is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero. + Read more on docs.microsoft.com. + + + Type: int The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area. + If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter. + Read more on docs.microsoft.com. + + + Type: int The width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinates to the right edge of the screen; the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameter are set to zero. + Read more on docs.microsoft.com. + + + Type: int The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows. To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window. + Read more on docs.microsoft.com. + + + Type: HMENU A handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window. + Read more on docs.microsoft.com. + + + Type: HINSTANCE A handle to the instance of the module to be associated with the window. + Read more on docs.microsoft.com. + + + Type: LPVOID Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns. If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed. + Read more on docs.microsoft.com. + + + Type: HWND If the function succeeds, the return value is a handle to the new window. If the function fails, the return value is NULL. To get extended error information, call GetLastError. This function typically fails for one of the following reasons: + This doc was truncated. + + + The CreateWindowEx function sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created. If the created window is a child window, its default position is at the bottom of the Z-order. If the created window is a top-level window, its default position is at the top of the Z-order (but beneath all topmost windows unless the created window is itself topmost). For information on controlling whether the Taskbar displays a button for the created window, see Managing Taskbar Buttons. For information on removing a window, see the DestroyWindow function. The following predefined control classes can be specified in the lpClassName parameter. Note the corresponding control styles you can use in the dwStyle parameter. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Calls the default window procedure to provide default processing for any window messages that an application does not process. (Unicode) + + Type: HWND A handle to the window procedure that received the message. + Read more on docs.microsoft.com. + + + Type: UINT The message. + Read more on docs.microsoft.com. + + + Type: WPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value is the result of the message processing and depends on the message. + + + > [!NOTE] > The winuser.h header defines DefWindowProc as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + Destroys the specified window. + + Type: HWND A handle to the window to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A thread cannot use DestroyWindow to destroy a window created by a different thread. If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style, a WM_PARENTNOTIFY message is sent to the parent. + Read more on docs.microsoft.com. + + + + + + + Dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function. (DispatchMessageW) + + Type: const MSG* A pointer to a structure that contains the message. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored. + + + The MSG structure must contain valid message values. If the lpmsg parameter points to a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The GetDC function retrieves a handle to a device context (DC) for the client area of a specified window or for the entire screen. + A handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen. + + If the function succeeds, the return value is a handle to the DC for the specified window's client area. If the function fails, the return value is NULL. + + + The GetDC function retrieves a common, class, or private DC depending on the class style of the specified window. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. However, for common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For example, the default font is System, which is a bitmap font. Because of this, the handle to a common DC returned by GetDC does not tell you what font, color, or brush was used when the window was drawn. To determine the font, call GetTextFace. Note that the handle to the DC can only be used by a single thread at any one time. After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. ReleaseDC must be called from the same thread that called GetDC. The number of DCs is limited only by available memory. + Read more on docs.microsoft.com. + + + + + + + Loads the specified cursor resource from the executable (.EXE) file associated with an application instance. (Unicode) + + Type: HINSTANCE A handle to an instance of the module whose executable file contains the cursor to be loaded. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The name of the cursor resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can also be used to create this value. To use one of the predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the following values. + This doc was truncated. + Read more on docs.microsoft.com. + + + Type: HCURSOR If the function succeeds, the return value is the handle to the newly loaded cursor. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The LoadCursor function loads the cursor resource only if it has not been loaded; otherwise, it retrieves the handle to the existing resource. This function returns a valid cursor handle only if the lpCursorName parameter is a pointer to a cursor resource. If lpCursorName is a pointer to any type of resource other than a cursor (such as an icon), the return value is not NULL, even though it is not a valid cursor handle. The LoadCursor function searches the cursor resource most appropriate for the cursor for the current display device. The cursor resource can be a color or monochrome bitmap.

DPI Virtualization

This API does not participate in DPI virtualization. The output returned is not affected by the DPI of the calling thread.
+ Read more on docs.microsoft.com. +
+
+ + + + + Dispatches incoming nonqueued messages, checks the thread message queue for a posted message, and retrieves the message (if any exist). (Unicode) + + Type: LPMSG A pointer to an MSG structure that receives message information. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the window whose messages are to be retrieved. The window must belong to the current thread. + If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed. If hWnd is -1, PeekMessage retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage. + Read more on docs.microsoft.com. + + + Type: UINT The value of the first message in the range of messages to be examined. Use WM_KEYFIRST (0x0100) to specify the first keyboard message or WM_MOUSEFIRST (0x0200) to specify the first mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + + Type: UINT The value of the last message in the range of messages to be examined. Use WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to specify the last mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + Type: UINT + + Type: BOOL If a message is available, the return value is nonzero. If no messages are available, the return value is zero. + + + PeekMessage retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax parameters; the high word is reserved for the system. Note that PeekMessage always retrieves WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax. During this call, the system dispatches (DispatchMessage) pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events. If no filter is specified, messages are processed in the following order: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. + + Type: int The application exit code. This value is used as the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future. When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + + Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. (RegisterClassW) + + Type: const WNDCLASS* A pointer to a WNDCLASS structure. You must fill the structure with the appropriate class attributes before passing it to the function. + Read more on docs.microsoft.com. + + + Type: ATOM If the function succeeds, the return value is a class atom that uniquely identifies the class being registered. This atom can only be used by the CreateWindow, CreateWindowEx, GetClassInfo, GetClassInfoEx, FindWindow, FindWindowEx, and UnregisterClass functions and the IActiveIMMap::FilterClientWindows method. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + If you register the window class by using RegisterClassA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterClassW, the application requests that the system pass text parameters of messages as Unicode. The IsWindowUnicode function enables applications to query the nature of each window. For more information on ANSI and Unicode functions, see Conventions for Function Prototypes. All window classes that an application registers are unregistered when it terminates. No window classes registered by a DLL are unregistered when the DLL is unloaded. A DLL must explicitly unregister its classes when it is unloaded. + Read more on docs.microsoft.com. + + + + The ReleaseDC function releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs. + A handle to the window whose DC is to be released. + A handle to the DC to be released. + + The return value indicates whether the DC was released. If the DC was released, the return value is 1. If the DC was not released, the return value is zero. + + + The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC. An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function. ReleaseDC must be called from the same thread that called GetDC. + Read more on docs.microsoft.com. + + + + Sets the specified window's show state. + + Type: HWND A handle to the window. + Read more on docs.microsoft.com. + + Type: int + + Type: BOOL If the window was previously visible, the return value is nonzero. If the window was previously hidden, the return value is zero. + + + To perform certain special effects when showing or hiding a window, use AnimateWindow. The first time an application calls ShowWindow, it should use the WinMain function's nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function's nCmdShow parameter. As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in the structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function. + + Type: const MSG* A pointer to an MSG structure that contains message information retrieved from the calling thread's message queue by using the GetMessage or PeekMessage function. + Read more on docs.microsoft.com. + + + Type: BOOL If the message is translated (that is, a character message is posted to the thread's message queue), the return value is nonzero. If the message is WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP, the return value is nonzero, regardless of the translation. If the message is not translated (that is, a character message is not posted to the thread's message queue), the return value is zero. + + + The TranslateMessage function does not modify the message pointed to by the lpMsg parameter. + WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message. TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver. If applications process virtual-key messages for some other purpose, they should not call TranslateMessage. For instance, an application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. + Handle to the window to be updated. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + + Learn more about this API from docs.microsoft.com. + + + - Generates a random seed in int value. + Represents a Win32 handle that can be closed with . - diff --git a/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/ref/StgSharp.dll b/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/ref/StgSharp.dll index 068495aa..014a67e8 100644 Binary files a/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/ref/StgSharp.dll and b/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/ref/StgSharp.dll differ diff --git a/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/refint/StgSharp.dll b/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/refint/StgSharp.dll index 068495aa..014a67e8 100644 Binary files a/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/refint/StgSharp.dll and b/æº�代ç �/StgSharp/obj/x64/RealDebug/netstandard2.1/refint/StgSharp.dll differ diff --git a/æº�代ç �/StgSharpC.dll b/æº�代ç �/StgSharpC.dll index ee7b2ba1..e451fb23 100644 Binary files a/æº�代ç �/StgSharpC.dll and b/æº�代ç �/StgSharpC.dll differ diff --git a/æº�代ç �/StgSharpC.lib b/æº�代ç �/StgSharpC.lib index b7524271..84ae644c 100644 Binary files a/æº�代ç �/StgSharpC.lib and b/æº�代ç �/StgSharpC.lib differ diff --git a/æº�代ç �/StgSharpC.pdb b/æº�代ç �/StgSharpC.pdb index 1af8355b..b3aae165 100644 Binary files a/æº�代ç �/StgSharpC.pdb and b/æº�代ç �/StgSharpC.pdb differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.cod b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.cod index c75a3af9..8dff95e2 100644 --- a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.cod +++ b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -38,66 +38,427 @@ PUBLIC _vfprintf_l PUBLIC __local_stdio_printf_options ; COMDAT pdata pdata SEGMENT -$pdata$loadImageData DD imagerel $LN5@loadImageD - DD imagerel $LN5@loadImageD+54 +$pdata$loadImageData DD imagerel $LN5 + DD imagerel $LN5+54 DD imagerel $unwind$loadImageData pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$linkShaderProgram DD imagerel $LN7@linkShader - DD imagerel $LN7@linkShader+116 +$pdata$linkShaderProgram DD imagerel $LN7 + DD imagerel $LN7+116 DD imagerel $unwind$linkShaderProgram pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$loadGlfuncDefault DD imagerel $LN19@loadGlfunc - DD imagerel $LN19@loadGlfunc+31 +$pdata$loadGlfuncDefault DD imagerel $LN19 + DD imagerel $LN19+31 DD imagerel $unwind$loadGlfuncDefault pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$initGL DD imagerel $LN4@initGL - DD imagerel $LN4@initGL+52 +$pdata$initGL DD imagerel $LN4 + DD imagerel $LN4+52 DD imagerel $unwind$initGL pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$printf DD imagerel $LN6@printf - DD imagerel $LN6@printf+85 +$pdata$printf DD imagerel $LN6 + DD imagerel $LN6+85 DD imagerel $unwind$printf pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$_vfprintf_l DD imagerel $LN4@vfprintf_l - DD imagerel $LN4@vfprintf_l+68 +$pdata$_vfprintf_l DD imagerel $LN4 + DD imagerel $LN4+68 DD imagerel $unwind$_vfprintf_l pdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$_vfprintf_l DQ 00009640f00060f01r ; 1.30596e-308 - DQ 0700b520f0008340fr ; 5.30195e+231 +$unwind$_vfprintf_l DD 060f01H + DD 09640fH + DD 08340fH + DD 0700b520fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$printf DQ 07017521b00041b01r ; 9.05146e+231 +$unwind$printf DD 041b01H + DD 07017521bH DD 030156016H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$initGL DQ 03002320600020601r ; 1.96423e-77 +$unwind$initGL DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$loadGlfuncDefault DQ 00000420400010401r ; 3.58617e-310 +$unwind$loadGlfuncDefault DD 010401H + DD 04204H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$linkShaderProgram DQ 0000a340a00041919r ; 1.41894e-308 +$unwind$linkShaderProgram DD 041919H + DD 0a340aH DD 07006520aH DD imagerel __GSHandlerCheck DD 028H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$loadImageData DQ 03002520600020601r ; 1.97773e-77 +$unwind$loadImageData DD 020601H + DD 030025206H +; Function compile flags: /Ogtpy +; File C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\corecrt_stdio_config.h +; COMDAT __local_stdio_printf_options +_TEXT SEGMENT +__local_stdio_printf_options PROC ; COMDAT + +; 91 : static unsigned __int64 _OptionsStorage; +; 92 : return &_OptionsStorage; + + 00000 48 8d 05 00 00 + 00 00 lea rax, OFFSET FLAT:?_OptionsStorage@?1??__local_stdio_printf_options@@9@9 ; `__local_stdio_printf_options'::`2'::_OptionsStorage + +; 93 : } + + 00007 c3 ret 0 +__local_stdio_printf_options ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\stdio.h +; COMDAT _vfprintf_l +_TEXT SEGMENT +_Stream$ = 64 +_Format$ = 72 +_Locale$dead$ = 80 +_ArgList$ = 88 +_vfprintf_l PROC ; COMDAT + +; 644 : { + +$LN4: + 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 30 sub rsp, 48 ; 00000030H + 0000f 49 8b d9 mov rbx, r9 + 00012 48 8b fa mov rdi, rdx + 00015 48 8b f1 mov rsi, rcx + +; 645 : return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + + 00018 e8 00 00 00 00 call __local_stdio_printf_options + 0001d 45 33 c9 xor r9d, r9d + 00020 48 89 5c 24 20 mov QWORD PTR [rsp+32], rbx + 00025 4c 8b c7 mov r8, rdi + 00028 48 8b d6 mov rdx, rsi + 0002b 48 8b 08 mov rcx, QWORD PTR [rax] + 0002e ff 15 00 00 00 + 00 call QWORD PTR __imp___stdio_common_vfprintf + +; 646 : } + + 00034 48 8b 5c 24 40 mov rbx, QWORD PTR [rsp+64] + 00039 48 8b 74 24 48 mov rsi, QWORD PTR [rsp+72] + 0003e 48 83 c4 30 add rsp, 48 ; 00000030H + 00042 5f pop rdi + 00043 c3 ret 0 +_vfprintf_l ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\stdio.h +; COMDAT printf +_TEXT SEGMENT +_Format$ = 80 +printf PROC ; COMDAT + +; 956 : { + +$LN6: + 00000 48 89 4c 24 08 mov QWORD PTR [rsp+8], rcx + 00005 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx + 0000a 4c 89 44 24 18 mov QWORD PTR [rsp+24], r8 + 0000f 4c 89 4c 24 20 mov QWORD PTR [rsp+32], r9 + 00014 53 push rbx + 00015 56 push rsi + 00016 57 push rdi + 00017 48 83 ec 30 sub rsp, 48 ; 00000030H + 0001b 48 8b f9 mov rdi, rcx + +; 957 : int _Result; +; 958 : va_list _ArgList; +; 959 : __crt_va_start(_ArgList, _Format); + + 0001e 48 8d 74 24 58 lea rsi, QWORD PTR _Format$[rsp+8] + +; 960 : _Result = _vfprintf_l(stdout, _Format, NULL, _ArgList); + + 00023 b9 01 00 00 00 mov ecx, 1 + 00028 ff 15 00 00 00 + 00 call QWORD PTR __imp___acrt_iob_func + 0002e 48 8b d8 mov rbx, rax + +; 645 : return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList); + + 00031 e8 00 00 00 00 call __local_stdio_printf_options + 00036 45 33 c9 xor r9d, r9d + 00039 48 89 74 24 20 mov QWORD PTR [rsp+32], rsi + 0003e 4c 8b c7 mov r8, rdi + 00041 48 8b d3 mov rdx, rbx + 00044 48 8b 08 mov rcx, QWORD PTR [rax] + 00047 ff 15 00 00 00 + 00 call QWORD PTR __imp___stdio_common_vfprintf + +; 961 : __crt_va_end(_ArgList); +; 962 : return _Result; +; 963 : } + + 0004d 48 83 c4 30 add rsp, 48 ; 00000030H + 00051 5f pop rdi + 00052 5e pop rsi + 00053 5b pop rbx + 00054 c3 ret 0 +printf ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT initGL +_TEXT SEGMENT +majorVersion$ = 48 +minorVersion$ = 56 +initGL PROC ; COMDAT + +; 11 : { + +$LN4: + 00000 40 53 push rbx + 00002 48 83 ec 20 sub rsp, 32 ; 00000020H + 00006 8b da mov ebx, edx + +; 12 : glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion); + + 00008 8b d1 mov edx, ecx + 0000a b9 02 20 02 00 mov ecx, 139266 ; 00022002H + 0000f e8 00 00 00 00 call glfwWindowHint + +; 13 : glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion); + + 00014 8b d3 mov edx, ebx + 00016 b9 03 20 02 00 mov ecx, 139267 ; 00022003H + 0001b e8 00 00 00 00 call glfwWindowHint + +; 14 : glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + 00020 ba 01 20 03 00 mov edx, 204801 ; 00032001H + 00025 b9 08 20 02 00 mov ecx, 139272 ; 00022008H + +; 15 : } + + 0002a 48 83 c4 20 add rsp, 32 ; 00000020H + 0002e 5b pop rbx + +; 14 : glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + 0002f e9 00 00 00 00 jmp glfwWindowHint +initGL ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT loadGlfuncDefault +_TEXT SEGMENT +procName$ = 48 +loadGlfuncDefault PROC ; COMDAT + +; 18 : { + +$LN19: + 00000 48 83 ec 28 sub rsp, 40 ; 00000028H + +; 19 : void* ret = glfwGetProcAddress(procName); + + 00004 e8 00 00 00 00 call glfwGetProcAddress + +; 20 : printf("%llu\n", (uint64_t)ret); + + 00009 48 8b d0 mov rdx, rax + 0000c 48 8d 0d 00 00 + 00 00 lea rcx, OFFSET FLAT:??_C@_05JMLLFKBP@?$CFllu?6@ + 00013 e8 00 00 00 00 call printf + +; 21 : if (ret = NULL) +; 22 : { +; 23 : *infolog = "Failed to load OpenGL api:"; +; 24 : for (size_t i = 0; i < sizeof(procName); i++) +; 25 : { +; 26 : infolog[30 + i] = procName[i]; +; 27 : } +; 28 : printf("%s\n", infolog); +; 29 : } +; 30 : return (GLFWglproc)ret; + + 00018 33 c0 xor eax, eax + +; 31 : } + + 0001a 48 83 c4 28 add rsp, 40 ; 00000028H + 0001e c3 ret 0 +loadGlfuncDefault ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT linkShaderProgram +_TEXT SEGMENT +success$ = 32 +__$ArrayPad$ = 40 +context$ = 64 +shaderProgram$ = 72 +linkShaderProgram PROC ; COMDAT + +; 34 : { + +$LN7: + 00000 48 89 5c 24 18 mov QWORD PTR [rsp+24], rbx + 00005 57 push rdi + 00006 48 83 ec 30 sub rsp, 48 ; 00000030H + 0000a 48 8b 05 00 00 + 00 00 mov rax, QWORD PTR __security_cookie + 00011 48 33 c4 xor rax, rsp + 00014 48 89 44 24 28 mov QWORD PTR __$ArrayPad$[rsp], rax + 00019 48 8b f9 mov rdi, rcx + 0001c 8b da mov ebx, edx + +; 35 : context->LinkProgram(shaderProgram); + + 0001e 8b ca mov ecx, edx + 00020 ff 97 80 22 00 + 00 call QWORD PTR [rdi+8832] + +; 36 : +; 37 : int success; +; 38 : context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + + 00026 4c 8d 44 24 20 lea r8, QWORD PTR success$[rsp] + 0002b ba 82 8b 00 00 mov edx, 35714 ; 00008b82H + 00030 8b cb mov ecx, ebx + 00032 ff 97 48 1a 00 + 00 call QWORD PTR [rdi+6728] + +; 39 : if (!success) + + 00038 83 7c 24 20 00 cmp DWORD PTR success$[rsp], 0 + 0003d 75 1b jne SHORT $LN2@linkShader + +; 40 : { +; 41 : context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog); + + 0003f 4c 8d 0d 00 00 + 00 00 lea r9, OFFSET FLAT:infolog + 00046 45 33 c0 xor r8d, r8d + 00049 ba 00 02 00 00 mov edx, 512 ; 00000200H + 0004e 8b cb mov ecx, ebx + 00050 ff 97 98 19 00 + 00 call QWORD PTR [rdi+6552] + +; 42 : return 0; + + 00056 33 c0 xor eax, eax + 00058 eb 02 jmp SHORT $LN3@linkShader +$LN2@linkShader: + +; 43 : } +; 44 : else +; 45 : { +; 46 : return shaderProgram; + + 0005a 8b c3 mov eax, ebx +$LN3@linkShader: + +; 47 : } +; 48 : } + + 0005c 48 8b 4c 24 28 mov rcx, QWORD PTR __$ArrayPad$[rsp] + 00061 48 33 cc xor rcx, rsp + 00064 e8 00 00 00 00 call __security_check_cookie + 00069 48 8b 5c 24 50 mov rbx, QWORD PTR [rsp+80] + 0006e 48 83 c4 30 add rsp, 48 ; 00000030H + 00072 5f pop rdi + 00073 c3 ret 0 +linkShaderProgram ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT loadImageData +_TEXT SEGMENT +location$ = 64 +out$ = 72 +loader$ = 80 +loadImageData PROC ; COMDAT + +; 51 : { + +$LN5: + 00000 40 53 push rbx + 00002 48 83 ec 30 sub rsp, 48 ; 00000030H + 00006 4d 8b d0 mov r10, r8 + +; 52 : if (loader == NULL) +; 53 : { +; 54 : loader = stbi_load; +; 55 : } +; 56 : out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0); + + 00009 c7 44 24 20 00 + 00 00 00 mov DWORD PTR [rsp+32], 0 + 00011 4d 85 d2 test r10, r10 + 00014 48 8d 05 00 00 + 00 00 lea rax, OFFSET FLAT:stbi_load + 0001b 4c 8d 4a 08 lea r9, QWORD PTR [rdx+8] + 0001f 48 8b da mov rbx, rdx + 00022 49 0f 45 c2 cmovne rax, r10 + 00026 4c 8d 42 04 lea r8, QWORD PTR [rdx+4] + 0002a ff d0 call rax + 0002c 48 89 43 10 mov QWORD PTR [rbx+16], rax + +; 57 : } + + 00030 48 83 c4 30 add rsp, 48 ; 00000030H + 00034 5b pop rbx + 00035 c3 ret 0 +loadImageData ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT unloadImageData +_TEXT SEGMENT +out$ = 8 +unloadImageData PROC ; COMDAT + +; 61 : free(out->pixelPtr); + + 00000 48 8b 49 10 mov rcx, QWORD PTR [rcx+16] + 00004 48 ff 25 00 00 + 00 00 rex_jmp QWORD PTR __imp_free +unloadImageData ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\StgSharpC.c +; COMDAT readLog +_TEXT SEGMENT +readLog PROC ; COMDAT + +; 66 : infolog[511] = '\0'; + + 00000 c6 05 ff 01 00 + 00 00 mov BYTE PTR infolog+511, 0 + +; 67 : return &infolog; + + 00007 48 8d 05 00 00 + 00 00 lea rax, OFFSET FLAT:infolog + +; 68 : } + + 0000e c3 ret 0 +readLog ENDP +_TEXT ENDS END diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.iobj b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.iobj index 2357ebc4..976294e3 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.iobj and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.iobj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.ipdb b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.ipdb index 99e1bce0..71f1178c 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.ipdb and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.ipdb differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.log b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.log index ea955296..95c9c521 100644 --- a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.log +++ b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.log @@ -30,12 +30,22 @@ D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharp stb_image.c D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\stb_image.c(832,17): warning C4047: “=â€�:“stbi_ucâ€�与“char [33]â€�的间接级别ä¸�å�Œ StgSharpC.c +C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared\minwindef.h(130,1): warning C4005: “APIENTRYâ€�: å®�é‡�定义 + (编译æº�文件“StgSharpC.câ€�) + D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\glfw3.h(123,1): + å�‚è§�“APIENTRYâ€�çš„å‰�一个定义 + +C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\wingdi.h(36,1): warning C4005: “WINGDIAPIâ€�: å®�é‡�定义 + (编译æº�文件“StgSharpC.câ€�) + D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\glfw3.h(133,1): + å�‚è§�“WINGDIAPIâ€�çš„å‰�一个定义 + D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\StgSharpC.c(23,18): warning C4047: “=â€�:“charâ€�与“char [27]â€�的间接级别ä¸�å�Œ D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\StgSharpC.c(67,5): warning C4047: “returnâ€�:“char *â€�与“char (*)[512]â€�的间接级别ä¸�å�Œ + vector.c 正在创建库 D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC.lib 和对象 D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC.exp 正在生æˆ�代ç � - 0 of 175 functions ( 0.0%) were compiled, the rest were copied from previous compilation. - 0 functions were new in current compilation - 0 functions had inline decision re-evaluated but remain unchanged + Previous IPDB was built with incompatible compiler, fall back to full compilation. + All 176 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. 已完æˆ�代ç �的生æˆ� StgSharpC.vcxproj -> D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC.dll diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.obj b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.obj index ff33c977..7116ac6e 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.obj and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.command.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.command.1.tlog index 2e44a06f..09845775 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.command.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.command.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.read.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.read.1.tlog index 3d3e91a3..440d5765 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.read.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.read.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.write.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.write.1.tlog index dc1ff6da..e3b871e1 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.write.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/CL.write.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/Cl.items.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/Cl.items.tlog index 884d4708..337e4a8d 100644 --- a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/Cl.items.tlog +++ b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/Cl.items.tlog @@ -4,3 +4,4 @@ D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharp D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\mat4.c;D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\x64\Release\mat4.obj D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\stb_image.c;D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\x64\Release\stb_image.obj D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\StgSharpC.c;D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\x64\Release\StgSharpC.obj +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\vector.c;D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\x64\Release\vector.obj diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.command.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.command.1.tlog index bbe7dc6e..ef20382d 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.command.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.command.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.read.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.read.1.tlog index 5e1b0a9a..7990633a 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.read.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.read.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.secondary.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.secondary.1.tlog index c9df490e..5f6c184d 100644 --- a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.secondary.1.tlog +++ b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.secondary.1.tlog @@ -1,4 +1,4 @@ -^D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3DLL.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3_MT.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\DLLMAIN.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT2.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT3.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT4.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\STB_IMAGE.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\STGSHARPC.OBJ +^D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3DLL.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\GLFW3_MT.LIB|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\DLLMAIN.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT2.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT3.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\MAT4.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\STB_IMAGE.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\STGSHARPC.OBJ|D:\NITLOADINDUSTRY\研究项目\1-FLAGSHIP\TH2020\PROJECTFILE\æº�代ç �\STGSHARPC\X64\RELEASE\VECTOR.OBJ D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC.lib D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC.EXP D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\æº�代ç �\StgSharpC\x64\Release\StgSharpC.IPDB diff --git a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.write.1.tlog b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.write.1.tlog index 391565b6..6e6792a1 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.write.1.tlog and b/æº�代ç �/StgSharpC/x64/Release/StgSharpC.tlog/link.write.1.tlog differ diff --git a/æº�代ç �/StgSharpC/x64/Release/dllmain.cod b/æº�代ç �/StgSharpC/x64/Release/dllmain.cod index 83d95d93..a274bf1f 100644 --- a/æº�代ç �/StgSharpC/x64/Release/dllmain.cod +++ b/æº�代ç �/StgSharpC/x64/Release/dllmain.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -204,4 +204,39 @@ CONST ENDS CONST SEGMENT __real@3f000000 DD 03f000000r ; 0.5 CONST ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\dllmain.c +; COMDAT DllMain +_TEXT SEGMENT +hModule$ = 8 +ul_reason_for_call$ = 16 +lpReserved$ = 24 +DllMain PROC ; COMDAT + +; 15 : switch (ul_reason_for_call) +; 16 : { +; 17 : case DLL_PROCESS_ATTACH: +; 18 : +; 19 : return 1; +; 20 : +; 21 : case DLL_THREAD_ATTACH: +; 22 : return 1; +; 23 : +; 24 : case DLL_THREAD_DETACH: +; 25 : return 1; +; 26 : +; 27 : case DLL_PROCESS_DETACH: +; 28 : return 1; + + 00000 b8 01 00 00 00 mov eax, 1 + +; 29 : +; 30 : break; +; 31 : } +; 32 : return TRUE; +; 33 : } + + 00005 c3 ret 0 +DllMain ENDP +_TEXT ENDS END diff --git a/æº�代ç �/StgSharpC/x64/Release/dllmain.obj b/æº�代ç �/StgSharpC/x64/Release/dllmain.obj index 6841febf..0a0d2163 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/dllmain.obj and b/æº�代ç �/StgSharpC/x64/Release/dllmain.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/mat2.cod b/æº�代ç �/StgSharpC/x64/Release/mat2.cod index a288a4fa..c735ecc3 100644 --- a/æº�代ç �/StgSharpC/x64/Release/mat2.cod +++ b/æº�代ç �/StgSharpC/x64/Release/mat2.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -8,4 +8,105 @@ EXTRN __imp__aligned_free:PROC PUBLIC deinit_mat2 PUBLIC transpose2to4 PUBLIC transpose2to3 +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat2.c +; COMDAT transpose2to3 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose2to3 PROC ; COMDAT + +; 6 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 21 movups xmm4, XMMWORD PTR [rcx] + 00003 0f 10 59 04 movups xmm3, XMMWORD PTR [rcx+4] + 00007 0f 28 d4 movaps xmm2, xmm4 + 0000a 0f 57 c0 xorps xmm0, xmm0 + 0000d 0f c6 d3 44 shufps xmm2, xmm3, 68 ; 00000044H + +; 7 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(3, 2, 3, 2)); +; 8 : +; 9 : target->colum[0] = _mm_shuffle_ps(t0, zeroVec, _MM_SHUFFLE(2, 0, 2, 0)); + + 00011 0f 28 ca movaps xmm1, xmm2 + 00014 0f c6 e3 ee shufps xmm4, xmm3, 238 ; 000000eeH + 00018 0f c6 c8 88 shufps xmm1, xmm0, 136 ; 00000088H + +; 10 : target->colum[1] = _mm_shuffle_ps(t0, zeroVec, _MM_SHUFFLE(3, 1, 3, 1)); + + 0001c 0f c6 d0 dd shufps xmm2, xmm0, 221 ; 000000ddH + +; 11 : target->colum[2] = _mm_shuffle_ps(t1, zeroVec, _MM_SHUFFLE(2, 0, 2, 0)); + + 00020 0f c6 e0 88 shufps xmm4, xmm0, 136 ; 00000088H + 00024 0f 11 0a movups XMMWORD PTR [rdx], xmm1 + 00027 0f 11 52 10 movups XMMWORD PTR [rdx+16], xmm2 + 0002b 0f 11 62 20 movups XMMWORD PTR [rdx+32], xmm4 + +; 12 : } + + 0002f c3 ret 0 +transpose2to3 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat2.c +; COMDAT transpose2to4 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose2to4 PROC ; COMDAT + +; 16 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 41 04 movups xmm0, XMMWORD PTR [rcx+4] + 00004 0f 10 19 movups xmm3, XMMWORD PTR [rcx] + 00007 0f 28 d3 movaps xmm2, xmm3 + +; 17 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(3, 2, 3, 2)); + + 0000a 0f c6 d8 ee shufps xmm3, xmm0, 238 ; 000000eeH + 0000e 0f c6 d0 44 shufps xmm2, xmm0, 68 ; 00000044H + 00012 0f 57 c0 xorps xmm0, xmm0 + +; 18 : +; 19 : target->colum[0] = _mm_shuffle_ps(t0, zeroVec, _MM_SHUFFLE(2, 0, 2, 0)); + + 00015 0f 28 ca movaps xmm1, xmm2 + +; 20 : target->colum[1] = _mm_shuffle_ps(t0, zeroVec, _MM_SHUFFLE(3, 1, 3, 1)); + + 00018 0f c6 d0 dd shufps xmm2, xmm0, 221 ; 000000ddH + 0001c 0f c6 c8 88 shufps xmm1, xmm0, 136 ; 00000088H + 00020 0f 11 0a movups XMMWORD PTR [rdx], xmm1 + +; 21 : target->colum[2] = _mm_shuffle_ps(t1, zeroVec, _MM_SHUFFLE(2, 0, 2, 0)); + + 00023 0f 28 cb movaps xmm1, xmm3 + 00026 0f c6 c8 88 shufps xmm1, xmm0, 136 ; 00000088H + +; 22 : target->colum[3] = _mm_shuffle_ps(t1, zeroVec, _MM_SHUFFLE(3, 1, 3, 1)); + + 0002a 0f c6 d8 dd shufps xmm3, xmm0, 221 ; 000000ddH + 0002e 0f 11 4a 20 movups XMMWORD PTR [rdx+32], xmm1 + 00032 0f 11 52 10 movups XMMWORD PTR [rdx+16], xmm2 + 00036 0f 11 5a 30 movups XMMWORD PTR [rdx+48], xmm3 + +; 23 : } + + 0003a c3 ret 0 +transpose2to4 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat2.c +; COMDAT deinit_mat2 +_TEXT SEGMENT +mat$ = 8 +deinit_mat2 PROC ; COMDAT + +; 27 : _aligned_free(mat); + + 00000 48 ff 25 00 00 + 00 00 rex_jmp QWORD PTR __imp__aligned_free +deinit_mat2 ENDP +_TEXT ENDS END diff --git a/æº�代ç �/StgSharpC/x64/Release/mat2.obj b/æº�代ç �/StgSharpC/x64/Release/mat2.obj index dddbd1b3..346a09fd 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/mat2.obj and b/æº�代ç �/StgSharpC/x64/Release/mat2.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/mat3.cod b/æº�代ç �/StgSharpC/x64/Release/mat3.cod index 1ec93128..a92e78b8 100644 --- a/æº�代ç �/StgSharpC/x64/Release/mat3.cod +++ b/æº�代ç �/StgSharpC/x64/Release/mat3.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -11,11 +11,303 @@ PUBLIC transpose3to3 PUBLIC transpose3to2 ; COMDAT pdata pdata SEGMENT -$pdata$transpose3to3 DD imagerel $LN4@transpose3 - DD imagerel $LN4@transpose3+83 +$pdata$transpose3to3 DD imagerel $LN4 + DD imagerel $LN4+83 DD imagerel $unwind$transpose3to3 ; COMDAT xdata xdata SEGMENT -$unwind$transpose3to3 DQ 00000681000031001r ; 5.653e-310 +$unwind$transpose3to3 DD 031001H + DD 06810H DD 02204H +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; COMDAT transpose3to2 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose3to2 PROC ; COMDAT + +; 7 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 41 34 movups xmm0, XMMWORD PTR [rcx+52] + 00004 0f 10 51 30 movups xmm2, XMMWORD PTR [rcx+48] + +; 8 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->m[0][2]), zeroVec, _MM_SHUFFLE(1, 0, 1, 0)); + + 00008 0f 10 49 38 movups xmm1, XMMWORD PTR [rcx+56] + 0000c 0f c6 d0 44 shufps xmm2, xmm0, 68 ; 00000044H + 00010 0f 57 c0 xorps xmm0, xmm0 + 00013 0f c6 c8 44 shufps xmm1, xmm0, 68 ; 00000044H + +; 9 : +; 10 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 00017 0f 28 c2 movaps xmm0, xmm2 + 0001a 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + +; 11 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); + + 0001e 0f c6 d1 dd shufps xmm2, xmm1, 221 ; 000000ddH + 00022 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + 00025 0f 11 52 10 movups XMMWORD PTR [rdx+16], xmm2 + +; 12 : } + + 00029 c3 ret 0 +transpose3to2 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; COMDAT transpose3to3 +_TEXT SEGMENT +source$ = 32 +target$ = 40 +transpose3to3 PROC ; COMDAT + +; 15 : { + +$LN4: + 00000 48 83 ec 18 sub rsp, 24 + +; 16 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(1, 0, 1, 0)); +; 17 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(3, 2, 3, 2)); +; 18 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->m[0][2]), zeroVec, _MM_SHUFFLE(1, 0, 1, 0)); + + 00004 0f 10 61 38 movups xmm4, XMMWORD PTR [rcx+56] + 00008 0f 10 69 34 movups xmm5, XMMWORD PTR [rcx+52] + 0000c 0f 29 34 24 movaps XMMWORD PTR [rsp], xmm6 + 00010 0f 57 c0 xorps xmm0, xmm0 + 00013 0f 10 71 30 movups xmm6, XMMWORD PTR [rcx+48] + 00017 0f 28 cc movaps xmm1, xmm4 + 0001a 0f 57 d2 xorps xmm2, xmm2 + 0001d 0f 28 de movaps xmm3, xmm6 + 00020 0f c6 c8 44 shufps xmm1, xmm0, 68 ; 00000044H + 00024 0f c6 dd 44 shufps xmm3, xmm5, 68 ; 00000044H + 00028 0f c6 f5 ee shufps xmm6, xmm5, 238 ; 000000eeH + +; 19 : __m128 t3 = _mm_shuffle_ps(ALIGN(source->m[0][2]), zeroVec, _MM_SHUFFLE(3, 2, 3, 2)); +; 20 : +; 21 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 0002c 0f 28 c3 movaps xmm0, xmm3 + 0002f 0f c6 e2 ee shufps xmm4, xmm2, 238 ; 000000eeH + +; 22 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); +; 23 : target->colum[2] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(2, 0, 2, 0)); + + 00033 0f c6 f4 88 shufps xmm6, xmm4, 136 ; 00000088H + 00037 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + 0003b 0f c6 d9 dd shufps xmm3, xmm1, 221 ; 000000ddH + 0003f 0f 11 72 20 movups XMMWORD PTR [rdx+32], xmm6 + +; 24 : } + + 00043 0f 28 34 24 movaps xmm6, XMMWORD PTR [rsp] + 00047 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + 0004a 0f 11 5a 10 movups XMMWORD PTR [rdx+16], xmm3 + 0004e 48 83 c4 18 add rsp, 24 + 00052 c3 ret 0 +transpose3to3 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; COMDAT transpose3to4 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose3to4 PROC ; COMDAT + +; 28 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 41 34 movups xmm0, XMMWORD PTR [rcx+52] + 00004 0f 10 61 30 movups xmm4, XMMWORD PTR [rcx+48] + +; 29 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->m[0][0]), ALIGN(source->m[0][1]), _MM_SHUFFLE(3, 2, 3, 2)); +; 30 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->m[0][2]), zeroVec, _MM_SHUFFLE(1, 0, 1, 0)); + + 00008 0f 10 51 38 movups xmm2, XMMWORD PTR [rcx+56] + 0000c 0f 28 dc movaps xmm3, xmm4 + 0000f 0f c6 e0 ee shufps xmm4, xmm0, 238 ; 000000eeH + 00013 0f c6 d8 44 shufps xmm3, xmm0, 68 ; 00000044H + 00017 0f 28 ca movaps xmm1, xmm2 + 0001a 0f 57 c0 xorps xmm0, xmm0 + 0001d 0f c6 c8 44 shufps xmm1, xmm0, 68 ; 00000044H + +; 31 : __m128 t3 = _mm_shuffle_ps(ALIGN(source->m[0][2]), zeroVec, _MM_SHUFFLE(3, 2, 3, 2)); + + 00021 0f c6 d0 ee shufps xmm2, xmm0, 238 ; 000000eeH + +; 32 : +; 33 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 00025 0f 28 c3 movaps xmm0, xmm3 + 00028 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + 0002c 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + +; 34 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); +; 35 : target->colum[2] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(2, 0, 2, 0)); + + 0002f 0f 28 c4 movaps xmm0, xmm4 + 00032 0f c6 c2 88 shufps xmm0, xmm2, 136 ; 00000088H + 00036 0f c6 d9 dd shufps xmm3, xmm1, 221 ; 000000ddH + +; 36 : target->colum[3] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 1, 3, 1)); + + 0003a 0f c6 e2 dd shufps xmm4, xmm2, 221 ; 000000ddH + 0003e 0f 11 42 20 movups XMMWORD PTR [rdx+32], xmm0 + 00042 0f 11 5a 10 movups XMMWORD PTR [rdx+16], xmm3 + 00046 0f 11 62 30 movups XMMWORD PTR [rdx+48], xmm4 + +; 37 : } + + 0004a c3 ret 0 +transpose3to4 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; COMDAT det_mat3_internal +_TEXT SEGMENT +c0$ = 8 +c1$ = 16 +c2$ = 24 +det_mat3_internal PROC ; COMDAT + +; 41 : //let adding row aligned +; 42 : __m128 addc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 0, 2, 1)); + + 00000 0f 10 1a movups xmm3, XMMWORD PTR [rdx] + +; 43 : __m128 addc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 1, 0, 2)); + + 00003 41 0f 10 10 movups xmm2, XMMWORD PTR [r8] + 00007 0f 28 e3 movaps xmm4, xmm3 + 0000a 0f c6 e3 c9 shufps xmm4, xmm3, 201 ; 000000c9H + 0000e 0f 28 c2 movaps xmm0, xmm2 + +; 44 : +; 45 : //let sub row aligned +; 46 : __m128 subc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 1, 0, 2)); +; 47 : __m128 subc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 0, 2, 1)); +; 48 : +; 49 : //multple all add row +; 50 : __m128 cache = _mm_mul_ps(c0, addc1); + + 00011 0f 59 21 mulps xmm4, XMMWORD PTR [rcx] + 00014 0f c6 c2 d2 shufps xmm0, xmm2, 210 ; 000000d2H + 00018 0f c6 db d2 shufps xmm3, xmm3, 210 ; 000000d2H + +; 51 : cache = _mm_mul_ps(cache, addc2); +; 52 : +; 53 : //multiple all sub row +; 54 : __m128 sub = _mm_mul_ps(c0, subc1); + + 0001c 0f 59 19 mulps xmm3, XMMWORD PTR [rcx] + 0001f 0f 59 e0 mulps xmm4, xmm0 + 00022 0f c6 d2 c9 shufps xmm2, xmm2, 201 ; 000000c9H + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 00026 0f 59 da mulps xmm3, xmm2 + +; 56 : +; 57 : //main-corner sub sub-corner +; 58 : cache = _mm_sub_ps(cache, sub); + + 00029 0f 5c e3 subps xmm4, xmm3 + +; 59 : +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 0002c 0f 28 c4 movaps xmm0, xmm4 + 0002f f2 0f 7c c4 haddps xmm0, xmm4 + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 00033 0f 58 c4 addps xmm0, xmm4 + +; 62 : +; 63 : return ret.m128_f32[2]; + + 00036 0f c6 c0 aa shufps xmm0, xmm0, 170 ; 000000aaH + +; 64 : } + + 0003a c3 ret 0 +det_mat3_internal ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; COMDAT det_mat3 +_TEXT SEGMENT +mat$ = 8 +det_mat3 PROC ; COMDAT + +; 68 : return det_mat3_internal( + + 00000 0f 10 59 10 movups xmm3, XMMWORD PTR [rcx+16] + 00004 0f 10 51 20 movups xmm2, XMMWORD PTR [rcx+32] + +; 42 : __m128 addc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 0, 2, 1)); + + 00008 0f 28 e3 movaps xmm4, xmm3 + 0000b 0f c6 e3 c9 shufps xmm4, xmm3, 201 ; 000000c9H + +; 43 : __m128 addc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 1, 0, 2)); + + 0000f 0f 28 c2 movaps xmm0, xmm2 + +; 44 : +; 45 : //let sub row aligned +; 46 : __m128 subc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 1, 0, 2)); +; 47 : __m128 subc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 0, 2, 1)); +; 48 : +; 49 : //multple all add row +; 50 : __m128 cache = _mm_mul_ps(c0, addc1); + + 00012 0f 59 21 mulps xmm4, XMMWORD PTR [rcx] + 00015 0f c6 c2 d2 shufps xmm0, xmm2, 210 ; 000000d2H + 00019 0f c6 db d2 shufps xmm3, xmm3, 210 ; 000000d2H + +; 51 : cache = _mm_mul_ps(cache, addc2); +; 52 : +; 53 : //multiple all sub row +; 54 : __m128 sub = _mm_mul_ps(c0, subc1); + + 0001d 0f 59 19 mulps xmm3, XMMWORD PTR [rcx] + 00020 0f 59 e0 mulps xmm4, xmm0 + 00023 0f c6 d2 c9 shufps xmm2, xmm2, 201 ; 000000c9H + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 00027 0f 59 da mulps xmm3, xmm2 + +; 56 : +; 57 : //main-corner sub sub-corner +; 58 : cache = _mm_sub_ps(cache, sub); + + 0002a 0f 5c e3 subps xmm4, xmm3 + +; 59 : +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 0002d 0f 28 c4 movaps xmm0, xmm4 + 00030 f2 0f 7c c4 haddps xmm0, xmm4 + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 00034 0f 58 c4 addps xmm0, xmm4 + +; 68 : return det_mat3_internal( + + 00037 0f c6 c0 aa shufps xmm0, xmm0, 170 ; 000000aaH + +; 69 : mat->colum[0], +; 70 : mat->colum[1], +; 71 : mat->colum[2] +; 72 : ); +; 73 : } + + 0003b c3 ret 0 +det_mat3 ENDP +_TEXT ENDS END diff --git a/æº�代ç �/StgSharpC/x64/Release/mat3.obj b/æº�代ç �/StgSharpC/x64/Release/mat3.obj index 0466d79d..6c95f0b8 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/mat3.obj and b/æº�代ç �/StgSharpC/x64/Release/mat3.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/mat4.cod b/æº�代ç �/StgSharpC/x64/Release/mat4.cod index a891618c..655f2c5d 100644 --- a/æº�代ç �/StgSharpC/x64/Release/mat4.cod +++ b/æº�代ç �/StgSharpC/x64/Release/mat4.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -11,24 +11,451 @@ PUBLIC transpose4to4 PUBLIC transpose4to2 ; COMDAT pdata pdata SEGMENT -$pdata$det_mat4 DD imagerel $LN12@det_mat4 - DD imagerel $LN12@det_mat4+293 +$pdata$det_mat4 DD imagerel $LN12 + DD imagerel $LN12+293 DD imagerel $unwind$det_mat4 pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$transpose4to3 DD imagerel $LN4@transpose4 - DD imagerel $LN4@transpose4+80 +$pdata$transpose4to3 DD imagerel $LN4 + DD imagerel $LN4+80 DD imagerel $unwind$transpose4to3 ; COMDAT xdata xdata SEGMENT -$unwind$transpose4to3 DQ 00000681400031401r ; 5.65385e-310 +$unwind$transpose4to3 DD 031401H + DD 06814H DD 02204H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$det_mat4 DQ 00000a835000b3501r ; 9.13753e-310 - DQ 00002881b0001982cr ; 3.52071e-309 - DQ 00004680e00037816r ; 6.12794e-309 +$unwind$det_mat4 DD 0b3501H + DD 0a835H + DD 01982cH + DD 02881bH + DD 037816H + DD 04680eH DD 0a207H +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; COMDAT transpose4to2 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose4to2 PROC ; COMDAT + +; 8 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->colum[0]), ALIGN(source->colum[1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 41 10 movups xmm0, XMMWORD PTR [rcx+16] + 00004 0f 10 11 movups xmm2, XMMWORD PTR [rcx] + +; 9 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->colum[2]), ALIGN(source->colum[3]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00007 0f 10 49 20 movups xmm1, XMMWORD PTR [rcx+32] + 0000b 0f c6 d0 44 shufps xmm2, xmm0, 68 ; 00000044H + 0000f 0f 10 41 30 movups xmm0, XMMWORD PTR [rcx+48] + 00013 0f c6 c8 44 shufps xmm1, xmm0, 68 ; 00000044H + +; 10 : +; 11 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 00017 0f 28 c2 movaps xmm0, xmm2 + 0001a 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + +; 12 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); + + 0001e 0f c6 d1 dd shufps xmm2, xmm1, 221 ; 000000ddH + 00022 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + 00025 0f 11 52 10 movups XMMWORD PTR [rdx+16], xmm2 + +; 13 : } + + 00029 c3 ret 0 +transpose4to2 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; COMDAT transpose4to4 +_TEXT SEGMENT +source$ = 8 +target$ = 16 +transpose4to4 PROC ; COMDAT + +; 17 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->colum[0]), ALIGN(source->colum[1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00000 0f 10 41 10 movups xmm0, XMMWORD PTR [rcx+16] + 00004 0f 10 21 movups xmm4, XMMWORD PTR [rcx] + +; 18 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->colum[0]), ALIGN(source->colum[1]), _MM_SHUFFLE(3, 2, 3, 2)); +; 19 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->colum[2]), ALIGN(source->colum[3]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00007 0f 10 51 20 movups xmm2, XMMWORD PTR [rcx+32] + 0000b 0f 28 dc movaps xmm3, xmm4 + 0000e 0f c6 e0 ee shufps xmm4, xmm0, 238 ; 000000eeH + 00012 0f c6 d8 44 shufps xmm3, xmm0, 68 ; 00000044H + 00016 0f 28 ca movaps xmm1, xmm2 + 00019 0f 10 41 30 movups xmm0, XMMWORD PTR [rcx+48] + 0001d 0f c6 c8 44 shufps xmm1, xmm0, 68 ; 00000044H + +; 20 : __m128 t3 = _mm_shuffle_ps(ALIGN(source->colum[2]), ALIGN(source->colum[3]), _MM_SHUFFLE(3, 2, 3, 2)); + + 00021 0f c6 d0 ee shufps xmm2, xmm0, 238 ; 000000eeH + +; 21 : +; 22 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 00025 0f 28 c3 movaps xmm0, xmm3 + 00028 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + 0002c 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + +; 23 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); +; 24 : target->colum[2] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(2, 0, 2, 0)); + + 0002f 0f 28 c4 movaps xmm0, xmm4 + 00032 0f c6 c2 88 shufps xmm0, xmm2, 136 ; 00000088H + 00036 0f c6 d9 dd shufps xmm3, xmm1, 221 ; 000000ddH + +; 25 : target->colum[3] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 1, 3, 1)); + + 0003a 0f c6 e2 dd shufps xmm4, xmm2, 221 ; 000000ddH + 0003e 0f 11 42 20 movups XMMWORD PTR [rdx+32], xmm0 + 00042 0f 11 5a 10 movups XMMWORD PTR [rdx+16], xmm3 + 00046 0f 11 62 30 movups XMMWORD PTR [rdx+48], xmm4 + +; 26 : } + + 0004a c3 ret 0 +transpose4to4 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; COMDAT transpose4to3 +_TEXT SEGMENT +source$ = 32 +target$ = 40 +transpose4to3 PROC ; COMDAT + +; 29 : { + +$LN4: + 00000 48 83 ec 18 sub rsp, 24 + +; 30 : __m128 t0 = _mm_shuffle_ps(ALIGN(source->colum[0]), ALIGN(source->colum[1]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00004 0f 10 61 10 movups xmm4, XMMWORD PTR [rcx+16] + +; 31 : __m128 t1 = _mm_shuffle_ps(ALIGN(source->colum[0]), ALIGN(source->colum[1]), _MM_SHUFFLE(3, 2, 3, 2)); +; 32 : __m128 t2 = _mm_shuffle_ps(ALIGN(source->colum[2]), ALIGN(source->colum[3]), _MM_SHUFFLE(1, 0, 1, 0)); + + 00008 0f 10 69 20 movups xmm5, XMMWORD PTR [rcx+32] + 0000c 0f 10 59 30 movups xmm3, XMMWORD PTR [rcx+48] + 00010 0f 29 34 24 movaps XMMWORD PTR [rsp], xmm6 + 00014 0f 28 cd movaps xmm1, xmm5 + 00017 0f 10 31 movups xmm6, XMMWORD PTR [rcx] + 0001a 0f c6 cb 44 shufps xmm1, xmm3, 68 ; 00000044H + 0001e 0f 28 d6 movaps xmm2, xmm6 + +; 33 : __m128 t3 = _mm_shuffle_ps(ALIGN(source->colum[2]), ALIGN(source->colum[3]), _MM_SHUFFLE(3, 2, 3, 2)); + + 00021 0f c6 eb ee shufps xmm5, xmm3, 238 ; 000000eeH + 00025 0f c6 d4 44 shufps xmm2, xmm4, 68 ; 00000044H + 00029 0f c6 f4 ee shufps xmm6, xmm4, 238 ; 000000eeH + +; 34 : +; 35 : target->colum[0] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0)); + + 0002d 0f 28 c2 movaps xmm0, xmm2 + +; 36 : target->colum[1] = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 3, 1)); +; 37 : target->colum[2] = _mm_shuffle_ps(t1, t3, _MM_SHUFFLE(2, 0, 2, 0)); + + 00030 0f c6 f5 88 shufps xmm6, xmm5, 136 ; 00000088H + 00034 0f c6 c1 88 shufps xmm0, xmm1, 136 ; 00000088H + 00038 0f c6 d1 dd shufps xmm2, xmm1, 221 ; 000000ddH + 0003c 0f 11 72 20 movups XMMWORD PTR [rdx+32], xmm6 + +; 38 : } + + 00040 0f 28 34 24 movaps xmm6, XMMWORD PTR [rsp] + 00044 0f 11 02 movups XMMWORD PTR [rdx], xmm0 + 00047 0f 11 52 10 movups XMMWORD PTR [rdx+16], xmm2 + 0004b 48 83 c4 18 add rsp, 24 + 0004f c3 ret 0 +transpose4to3 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; COMDAT det_mat4 +_TEXT SEGMENT +matPtr$ = 96 +transpose$ = 104 +det_mat4 PROC ; COMDAT + +; 41 : { + +$LN12: + 00000 48 8b c4 mov rax, rsp + 00003 48 83 ec 58 sub rsp, 88 ; 00000058H + +; 42 : __m128 mc0 = ALIGN(matPtr->colum[0]); + + 00007 0f 10 29 movups xmm5, XMMWORD PTR [rcx] + 0000a 0f 29 70 e8 movaps XMMWORD PTR [rax-24], xmm6 + +; 47 : __m128 cogeneration = _mm_set_ps( + + 0000e 0f 10 71 30 movups xmm6, XMMWORD PTR [rcx+48] + 00012 0f 29 78 d8 movaps XMMWORD PTR [rax-40], xmm7 + 00016 44 0f 29 40 c8 movaps XMMWORD PTR [rax-56], xmm8 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 43 : __m128 addc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 1, 0, 2)); + + 0001b 0f 28 de movaps xmm3, xmm6 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 47 : __m128 cogeneration = _mm_set_ps( + + 0001e 44 0f 10 41 20 movups xmm8, XMMWORD PTR [rcx+32] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 43 : __m128 addc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 1, 0, 2)); + + 00023 0f c6 de d2 shufps xmm3, xmm6, 210 ; 000000d2H + 00027 44 0f 29 48 b8 movaps XMMWORD PTR [rax-72], xmm9 + +; 42 : __m128 addc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 0, 2, 1)); + + 0002c 45 0f 28 c8 movaps xmm9, xmm8 + 00030 44 0f 29 14 24 movaps XMMWORD PTR [rsp], xmm10 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 43 : __m128 mc1 = ALIGN(matPtr->colum[1]); + + 00035 44 0f 10 51 10 movups xmm10, XMMWORD PTR [rcx+16] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 42 : __m128 addc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 0, 2, 1)); + + 0003a 45 0f c6 c8 c9 shufps xmm9, xmm8, 201 ; 000000c9H + +; 44 : +; 45 : //let sub row aligned +; 46 : __m128 subc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 1, 0, 2)); + + 0003f 45 0f c6 c0 d2 shufps xmm8, xmm8, 210 ; 000000d2H + +; 42 : __m128 addc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 0, 2, 1)); + + 00044 41 0f 28 d2 movaps xmm2, xmm10 + 00048 41 0f c6 d2 c9 shufps xmm2, xmm10, 201 ; 000000c9H + +; 54 : __m128 sub = _mm_mul_ps(c0, subc1); + + 0004d 41 0f 28 c0 movaps xmm0, xmm8 + 00051 41 0f 59 c2 mulps xmm0, xmm10 + 00055 41 0f 28 c9 movaps xmm1, xmm9 + 00059 41 0f 59 ca mulps xmm1, xmm10 + 0005d 0f c6 f6 c9 shufps xmm6, xmm6, 201 ; 000000c9H + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 00061 0f 59 c6 mulps xmm0, xmm6 + 00064 0f 59 cb mulps xmm1, xmm3 + +; 46 : __m128 subc1 = _mm_shuffle_ps(c1, c1, _MM_SHUFFLE(3, 1, 0, 2)); + + 00067 45 0f c6 d2 d2 shufps xmm10, xmm10, 210 ; 000000d2H + +; 47 : __m128 subc2 = _mm_shuffle_ps(c2, c2, _MM_SHUFFLE(3, 0, 2, 1)); +; 48 : +; 49 : //multple all add row +; 50 : __m128 cache = _mm_mul_ps(c0, addc1); + + 0006c 0f 59 d5 mulps xmm2, xmm5 + +; 58 : cache = _mm_sub_ps(cache, sub); + + 0006f 0f 5c c8 subps xmm1, xmm0 + +; 54 : __m128 sub = _mm_mul_ps(c0, subc1); + + 00072 44 0f 59 d5 mulps xmm10, xmm5 + 00076 41 0f 28 c0 movaps xmm0, xmm8 + 0007a 0f 59 c5 mulps xmm0, xmm5 + +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 0007d 0f 28 f9 movaps xmm7, xmm1 + 00080 f2 0f 7c f9 haddps xmm7, xmm1 + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 00084 0f 59 c6 mulps xmm0, xmm6 + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 00087 0f 58 f9 addps xmm7, xmm1 + +; 50 : __m128 cache = _mm_mul_ps(c0, addc1); + + 0008a 41 0f 28 c9 movaps xmm1, xmm9 + 0008e 0f 59 cd mulps xmm1, xmm5 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 47 : __m128 cogeneration = _mm_set_ps( + + 00091 0f c6 ff aa shufps xmm7, xmm7, 170 ; 000000aaH +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 51 : cache = _mm_mul_ps(cache, addc2); + + 00095 0f 59 cb mulps xmm1, xmm3 + +; 58 : cache = _mm_sub_ps(cache, sub); + + 00098 0f 5c c8 subps xmm1, xmm0 + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 0009b 41 0f 28 c2 movaps xmm0, xmm10 + 0009f 0f 59 c6 mulps xmm0, xmm6 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 57 : } + + 000a2 0f 28 70 e8 movaps xmm6, XMMWORD PTR [rax-24] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 55 : sub = _mm_mul_ps(sub, subc2); + + 000a6 45 0f 59 d1 mulps xmm10, xmm9 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 57 : } + + 000aa 44 0f 28 48 b8 movaps xmm9, XMMWORD PTR [rax-72] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 000af 0f 28 e1 movaps xmm4, xmm1 + 000b2 f2 0f 7c e1 haddps xmm4, xmm1 + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 000b6 0f 58 e1 addps xmm4, xmm1 + +; 51 : cache = _mm_mul_ps(cache, addc2); + + 000b9 0f 28 ca movaps xmm1, xmm2 + 000bc 0f 59 cb mulps xmm1, xmm3 + 000bf 41 0f 59 d0 mulps xmm2, xmm8 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 57 : } + + 000c3 44 0f 28 40 c8 movaps xmm8, XMMWORD PTR [rax-56] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 58 : cache = _mm_sub_ps(cache, sub); + + 000c8 0f 5c c8 subps xmm1, xmm0 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 47 : __m128 cogeneration = _mm_set_ps( + + 000cb 0f c6 e4 aa shufps xmm4, xmm4, 170 ; 000000aaH +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 58 : cache = _mm_sub_ps(cache, sub); + + 000cf 41 0f 5c d2 subps xmm2, xmm10 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 57 : } + + 000d3 44 0f 28 14 24 movaps xmm10, XMMWORD PTR [rsp] +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 000d8 0f 28 d9 movaps xmm3, xmm1 + 000db f2 0f 7c d9 haddps xmm3, xmm1 + 000df 0f 28 c2 movaps xmm0, xmm2 + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 000e2 0f 58 d9 addps xmm3, xmm1 + +; 60 : __m128 ret = _mm_hadd_ps(cache, cache); //element 1 add element 2 + + 000e5 f2 0f 7c c2 haddps xmm0, xmm2 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 47 : __m128 cogeneration = _mm_set_ps( + + 000e9 0f c6 db aa shufps xmm3, xmm3, 170 ; 000000aaH + 000ed 0f 28 cb movaps xmm1, xmm3 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat3.c + +; 61 : ret = _mm_add_ps(ret, cache); //(e1 add e2) add element 3 + + 000f0 0f 58 c2 addps xmm0, xmm2 +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c + +; 47 : __m128 cogeneration = _mm_set_ps( + + 000f3 0f 28 df movaps xmm3, xmm7 + +; 57 : } + + 000f6 0f 28 78 d8 movaps xmm7, XMMWORD PTR [rax-40] + 000fa 0f 14 dc unpcklps xmm3, xmm4 + 000fd 0f c6 c0 aa shufps xmm0, xmm0, 170 ; 000000aaH + 00101 0f 14 c8 unpcklps xmm1, xmm0 + 00104 0f 10 42 30 movups xmm0, XMMWORD PTR [rdx+48] + 00108 0f 16 d9 movlhps xmm3, xmm1 + 0010b 0f 59 d8 mulps xmm3, xmm0 + 0010e f2 0f 7d db hsubps xmm3, xmm3 + 00112 f2 0f 7c db haddps xmm3, xmm3 + 00116 0f 57 1d 00 00 + 00 00 xorps xmm3, DWORD PTR __xmm@80000000800000008000000080000000 + 0011d 0f 28 c3 movaps xmm0, xmm3 + 00120 48 83 c4 58 add rsp, 88 ; 00000058H + 00124 c3 ret 0 +det_mat4 ENDP +_TEXT ENDS +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\mat4.c +; COMDAT deinit_mat4 +_TEXT SEGMENT +matPtr$ = 8 +deinit_mat4 PROC ; COMDAT + +; 61 : _aligned_free(matPtr); + + 00000 48 ff 25 00 00 + 00 00 rex_jmp QWORD PTR __imp__aligned_free +deinit_mat4 ENDP +_TEXT ENDS END diff --git a/æº�代ç �/StgSharpC/x64/Release/mat4.obj b/æº�代ç �/StgSharpC/x64/Release/mat4.obj index 24498968..58067b86 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/mat4.obj and b/æº�代ç �/StgSharpC/x64/Release/mat4.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/stb_image.cod b/æº�代ç �/StgSharpC/x64/Release/stb_image.cod index a43ff7db..19d0686a 100644 --- a/æº�代ç �/StgSharpC/x64/Release/stb_image.cod +++ b/æº�代ç �/StgSharpC/x64/Release/stb_image.cod @@ -1,4 +1,4 @@ -; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33519.0 +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 include listing.inc @@ -1751,8 +1751,8 @@ $pdata$stbi__get_chunk_header DD imagerel stbi__get_chunk_header pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$stbi_zlib_decode_malloc_guesssize_headerflag DD imagerel $LN16@stbi_zlib_ - DD imagerel $LN16@stbi_zlib_+185 +$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 @@ -2477,14 +2477,14 @@ $pdata$stbi__refill_buffer DD imagerel stbi__refill_buffer pdata ENDS ; COMDAT pdata pdata SEGMENT -$pdata$stbi_load_from_file DD imagerel $LN9@stbi_load_ - DD imagerel $LN9@stbi_load_+157 +$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@stbi_load - DD imagerel $LN13@stbi_load+187 +$pdata$stbi_load DD imagerel $LN13 + DD imagerel $LN13+187 DD imagerel $unwind$stbi_load pdata ENDS ; COMDAT pdata @@ -2567,37 +2567,47 @@ stbi__stdio_callbacks DQ FLAT:stbi__stdio_read _DATA ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__cpuid3 DQ 03002120600020601r ; 1.95074e-77 +$unwind$stbi__cpuid3 DD 020601H + DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__sse2_available DQ 03002120600020601r ; 1.95074e-77 +$unwind$stbi__sse2_available DD 020601H + DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__start_callbacks DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__start_callbacks DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__stdio_skip DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__stdio_skip DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__stdio_eof DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__stdio_eof DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__load_main DQ 000150114000a2619r ; 2.921e-308 - DQ 0c007d009e00bf00dr ; -2.97658 - DQ 03002500360047005r ; 1.97688e-77 +$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 DQ 00008641400081401r ; 1.1669e-308 - DQ 00006341400075414r ; 8.62693e-309 +$unwind$stbi__convert_16_to_8 DD 081401H + DD 086414H + DD 075414H + DD 063414H DD 070103214H xdata ENDS ; COMDAT xdata @@ -2609,9 +2619,12 @@ $chain$6$stbi__vertical_flip DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__vertical_flip DQ 00107e423000c2321r ; 1.08871e-303 - DQ 0010974140108d418r ; 1.1599e-303 - DQ 0010b540c010a6410r ; 1.24534e-303 +$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 @@ -2619,42 +2632,51 @@ $chain$5$stbi__vertical_flip DQ 00107e423000c2321r ; 1.08871e-303 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__vertical_flip DQ 0010d010e00042019r ; 1.3217e-303 +$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 DQ 0f008b20c00061b19r ; -4.79253e+231 - DQ 0300260037004e006r ; 1.98363e-77 +$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 DQ 00000620400011319r ; 5.32451e-310 +$unwind$stbi__fopen DD 011319H + DD 06204H DD imagerel __GSHandlerCheck DD 028H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi_load DQ 0e007720b00061a19r ; -3.92941e+154 - DQ 03002500360047005r ; 1.97688e-77 +$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 DQ 00024010e00072019r ; 5.56383e-308 - DQ 0500360047005e007r ; 2.80435e+77 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__refill_buffer DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata @@ -2666,44 +2688,54 @@ $chain$1$stbi__get8 DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__get8 DQ 00006740500020521r ; 8.97428e-309 +$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 DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__get8 DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__at_eof DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__at_eof DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__getn DQ 0000b741e000c1e01r ; 1.59282e-308 - DQ 00009541e000a641er ; 1.2973e-308 - DQ 0f01a321e0008341er ; -1.01674e+232 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__get16be DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__get32be DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__get32be DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__get16le DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__get16le DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__get32le DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__get32le DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata @@ -2715,36 +2747,45 @@ $chain$6$stbi__convert_format DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__convert_format DQ 0000cf40000020021r ; 1.80135e-308 +$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 DQ 0000cf40000060021r ; 1.80135e-308 - DQ 0000a7400000be400r ; 1.45369e-308 +$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 DQ 0000be47700067721r ; 1.65385e-308 - DQ 0000cf405000a7470r ; 1.80136e-308 +$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 DQ 0d008320c00060c01r ; -3.50206e+77 - DQ 0300250036004c006r ; 1.97688e-77 +$unwind$stbi__convert_format DD 060c01H + DD 0d008320cH + DD 06004c006H + DD 030025003H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__convert_format16 DQ 0000af40000060021r ; 1.52322e-308 - DQ 0000834000009e400r ; 1.14078e-308 +$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 @@ -2758,7 +2799,8 @@ $chain$3$stbi__convert_format16 DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__convert_format16 DQ 0000af40c00040c21r ; 1.52324e-308 +$chain$2$stbi__convert_format16 DD 040c21H + DD 0af40cH DD 083405H DD imagerel stbi__convert_format16+49 DD imagerel stbi__convert_format16+130 @@ -2766,15 +2808,18 @@ $chain$2$stbi__convert_format16 DQ 0000af40c00040c21r ; 1.52324e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__convert_format16 DQ 00009e40500020521r ; 1.37547e-308 +$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 DQ 0000b540d00060d01r ; 1.5754e-308 - DQ 060067007c009320dr ; 3.76049e+154 +$unwind$stbi__convert_format16 DD 060d01H + DD 0b540dH + DD 0c009320dH + DD 060067007H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -2785,10 +2830,14 @@ $chain$8$stbi__hdr_to_ldr DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$7$stbi__hdr_to_ldr DQ 00004885800105821r ; 6.30335e-309 - DQ 00006683b00057848r ; 8.91024e-309 - DQ 0000fe42b000ef433r ; 2.20995e-308 - DQ 00016c4180017d423r ; 3.166e-308 +$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 @@ -2796,12 +2845,14 @@ $chain$7$stbi__hdr_to_ldr DQ 00004885800105821r ; 6.30335e-309 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__hdr_to_ldr DQ 07008f20f00040f01r ; 4.84105e+231 +$unwind$stbi__hdr_to_ldr DD 040f01H + DD 07008f20fH DD 030066007H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__build_huffman DQ 0000ae40000040021r ; 1.51453e-308 +$chain$5$stbi__build_huffman DD 040021H + DD 0ae400H DD 097400H DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 @@ -2823,14 +2874,16 @@ $chain$3$stbi__build_huffman DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__build_huffman DQ 00008540500020521r ; 1.15818e-308 +$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 DQ 0000ae41000041021r ; 1.51456e-308 +$chain$1$stbi__build_huffman DD 041021H + DD 0ae410H DD 097405H DD imagerel stbi__build_huffman DD imagerel stbi__build_huffman+96 @@ -2838,129 +2891,168 @@ $chain$1$stbi__build_huffman DQ 0000ae41000041021r ; 1.51456e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__build_huffman DQ 0f005320900040901r ; -4.11329e+231 +$unwind$stbi__build_huffman DD 040901H + DD 0f0053209H DD 030026003H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__build_fast_ac DQ 00003741500071501r ; 4.80261e-309 - DQ 0000454060002340dr ; 6.01913e-309 +$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 DQ 00006641200061201r ; 8.88764e-309 - DQ 07006320a0007340ar ; 4.30736e+231 -xdata ENDS -; COMDAT xdata -xdata SEGMENT -$unwind$stbi__jpeg_huff_decode DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__grow_buffer_unsafe DD 061201H + DD 066412H + DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__extend_receive DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__jpeg_huff_decode DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__jpeg_get_bits DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__extend_receive DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__jpeg_get_bit DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__jpeg_get_bits DD 040a01H + DD 06340aH + DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$6$stbi__jpeg_decode_block DQ 0000cd40000060021r ; 1.78397e-308 - DQ 0000a6400000bc400r ; 1.44499e-308 +$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 DQ 0000a641b00061b21r ; 1.44505e-308 - DQ 0000bc400000cd405r ; 1.63621e-308 +$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 DQ 0000bc40500020521r ; 1.63622e-308 +$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 DQ 0f008320c00060c01r ; -4.69549e+231 - DQ 0300250037004e006r ; 1.97688e-77 +$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 DQ 00009f474000a7401r ; 1.3844e-308 - DQ 0000a340d0008546fr ; 1.41895e-308 - DQ 060067007e009320dr ; 3.76049e+154 +$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 DQ 00004e479000c7901r ; 6.80382e-309 - DQ 0000c546f0005d474r ; 1.71467e-308 - DQ 0700dc00ff0115215r ; 5.77347e+231 +$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 DQ 000303417000b2919r ; 9.01348e-308 - DQ 0e00ef01000260117r ; -5.18509e+154 - DQ 060077008c00ad00cr ; 3.92809e+154 +$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 DQ 00008f88f00168f01r ; 1.24756e-308 - DQ 0000ad87f0009e887r ; 1.50828e-308 - DQ 0000cb872000bc877r ; 1.769e-308 - DQ 0000e9868000da86dr ; 2.02973e-308 - DQ 00010782e000f8839r ; 2.29036e-308 - DQ 00025010a00116829r ; 5.84195e-308 +$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 DQ 00006340000020021r ; 8.62651e-309 +$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 DQ 00006340000020021r ; 8.62651e-309 +$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 DQ 00006340500020521r ; 8.62661e-309 +$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 DQ 07002320600020601r ; 3.53109e+231 +$unwind$stbi__get_marker DD 020601H + DD 070023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__parse_entropy_coded_data DQ 00025641f000d3119r ; 5.9496e-308 - DQ 00023341f0024541fr ; 5.34118e-308 - DQ 0e016f018001c011fr ; -7.68866e+154 - DQ 000007010c012d014r ; 6.08774e-310 +$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 @@ -2980,9 +3072,12 @@ $chain$7$stbi__jpeg_finish DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$6$stbi__jpeg_finish DQ 00004f41f000c1f21r ; 6.88883e-309 - DQ 0000774170006c41br ; 1.03653e-308 - DQ 0000b540f000c6413r ; 1.5754e-308 +$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 @@ -2990,20 +3085,25 @@ $chain$6$stbi__jpeg_finish DQ 00004f41f000c1f21r ; 6.88883e-309 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__jpeg_finish DQ 00005d40400020421r ; 8.10509e-309 +$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 DQ 0e005720900020901r ; -3.59421e+154 +$unwind$stbi__jpeg_finish DD 020901H + DD 0e0057209H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__process_marker DQ 00019641f000c2e19r ; 3.53107e-308 - DQ 00017341f0018541fr ; 3.22686e-308 - DQ 0d014e016f018f21fr ; -6.043e+77 +$unwind$stbi__process_marker DD 0c2e19H + DD 019641fH + DD 018541fH + DD 017341fH + DD 0f018f21fH + DD 0d014e016H DD 07010c012H DD imagerel __GSHandlerCheck DD 070H @@ -3017,7 +3117,8 @@ $chain$4$stbi__process_scan_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$3$stbi__process_scan_header DQ 00007e40000040021r ; 1.09733e-308 +$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 @@ -3025,7 +3126,8 @@ $chain$3$stbi__process_scan_header DQ 00007e40000040021r ; 1.09733e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$1$stbi__process_scan_header DQ 00007e40c00040c21r ; 1.09735e-308 +$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 @@ -3033,8 +3135,10 @@ $chain$1$stbi__process_scan_header DQ 00007e40c00040c21r ; 1.09735e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__process_scan_header DQ 00009640f00060f01r ; 1.30596e-308 - DQ 0700b320f0008340fr ; 5.2777e+231 +$unwind$stbi__process_scan_header DD 060f01H + DD 09640fH + DD 08340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3045,15 +3149,18 @@ $chain$3$stbi__free_jpeg_components DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__free_jpeg_components DQ 00008741800061821r ; 1.1756e-308 - DQ 00006340500075411r ; 8.62661e-309 +$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 DQ 06002320600020601r ; 3.04951e+154 +$unwind$stbi__free_jpeg_components DD 020601H + DD 060023206H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3064,46 +3171,57 @@ $chain$7$stbi__process_frame_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$6$stbi__process_frame_header DQ 0000de40000060021r ; 1.93173e-308 - DQ 0000ac400000cd400r ; 1.49714e-308 +$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 DQ 0000de41800061821r ; 1.93178e-308 - DQ 0000ac400000cd405r ; 1.49714e-308 +$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 DQ 0000ac40500020521r ; 1.49716e-308 +$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 DQ 0f00a320e00060e01r ; -5.08363e+231 - DQ 03005500660077008r ; 2.30074e-77 +$unwind$stbi__process_frame_header DD 060e01H + DD 0f00a320eH + DD 060077008H + DD 030055006H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__decode_jpeg_header DQ 00008641400081401r ; 1.1669e-308 - DQ 00006341400075414r ; 8.62693e-309 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__skip_jpeg_junk_at_end DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__decode_jpeg_image DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__decode_jpeg_image DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata @@ -3115,26 +3233,33 @@ $chain$3$stbi__resample_row_v_2 DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__resample_row_v_2 DQ 00004740f00060f21r ; 6.19315e-309 - DQ 0000254050003640ar ; 3.23776e-309 +$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 DQ 00000300200010201r ; 2.60793e-310 +$unwind$stbi__resample_row_v_2 DD 010201H + DD 03002H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__resample_row_h_2 DQ 00000744000074001r ; 6.31506e-310 - DQ 00002342c00036434r ; 3.06476e-309 +$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 DQ 00002743e00053e01r ; 3.41281e-309 - DQ 00000600600033406r ; 5.21629e-310 +$unwind$stbi__resample_row_hv_2 DD 053e01H + DD 02743eH + DD 033406H + DD 06006H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3145,15 +3270,18 @@ $chain$4$stbi__resample_row_hv_2_simd DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$3$stbi__resample_row_hv_2_simd DQ 00006f41c00061c21r ; 9.6701e-309 - DQ 0000454050005e40cr ; 6.0191e-309 +$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 DQ 00003343900043901r ; 4.4557e-309 +$unwind$stbi__resample_row_hv_2_simd DD 043901H + DD 033439H DD 060027003H xdata ENDS ; COMDAT xdata @@ -3165,7 +3293,8 @@ $chain$2$stbi__YCbCr_to_RGB_row DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$1$stbi__YCbCr_to_RGB_row DQ 00004f41900041921r ; 6.8887e-309 +$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 @@ -3173,8 +3302,10 @@ $chain$1$stbi__YCbCr_to_RGB_row DQ 00004f41900041921r ; 6.8887e-309 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__YCbCr_to_RGB_row DQ 00006540d00060d01r ; 8.80062e-309 - DQ 0700be00d0005340dr ; 5.40959e+231 +$unwind$stbi__YCbCr_to_RGB_row DD 060d01H + DD 06540dH + DD 05340dH + DD 0700be00dH xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3185,7 +3316,8 @@ $chain$10$stbi__YCbCr_to_RGB_simd DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$9$stbi__YCbCr_to_RGB_simd DQ 00011e41700041721r ; 2.48805e-308 +$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 @@ -3207,28 +3339,35 @@ $chain$6$stbi__YCbCr_to_RGB_simd DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__YCbCr_to_RGB_simd DQ 00005680500020521r ; 7.51842e-309 +$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 DQ 00000b83f000a3f21r ; 1.00088e-309 - DQ 0000298220001a831r ; 3.60777e-309 - DQ 00004780500038813r ; 6.21467e-309 +$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 DQ 00012540d00060d01r ; 2.54887e-308 - DQ 060067007f009b20dr ; 3.76049e+154 +$unwind$stbi__YCbCr_to_RGB_simd DD 060d01H + DD 012540dH + DD 0f009b20dH + DD 060067007H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__setup_jpeg DQ 03002120600020601r ; 1.95074e-77 +$unwind$stbi__setup_jpeg DD 020601H + DD 030021206H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3239,9 +3378,12 @@ $chain$10$load_jpeg_image DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$9$load_jpeg_image DQ 0002fe400000a0021r ; 8.86987e-308 - DQ 0003174000030c400r ; 9.70862e-308 - DQ 00033340000325400r ; 1.06821e-307 +$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 @@ -3262,8 +3404,10 @@ $chain$7$load_jpeg_image DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$6$load_jpeg_image DQ 0002fe40000080021r ; 8.86987e-308 - DQ 00032540000317400r ; 1.01954e-307 +$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 @@ -3278,8 +3422,10 @@ $chain$5$load_jpeg_image DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$4$load_jpeg_image DQ 0002fe42600082621r ; 8.87004e-308 - DQ 0003254130031741er ; 1.01955e-307 +$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 @@ -3287,28 +3433,36 @@ $chain$4$load_jpeg_image DQ 0002fe42600082621r ; 8.87004e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$load_jpeg_image DQ 00030c40800020821r ; 9.32626e-308 +$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 DQ 00034010d00051f19r ; 1.11277e-307 - DQ 000006002d004f006r ; 5.21561e-310 +$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 DQ 0000d741a000a1a01r ; 1.87094e-308 - DQ 0000b541a000c641ar ; 1.57542e-308 - DQ 0e016721a000a341ar ; -7.52369e+154 +$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 DQ 00008345900065901r ; 1.14097e-308 - DQ 07006520a0009640ar ; 4.33162e+231 +$unwind$stbi__jpeg_test DD 065901H + DD 083459H + DD 09640aH + DD 07006520aH xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3319,7 +3473,8 @@ $chain$3$stbi__zbuild_huffman DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__zbuild_huffman DQ 00020640000020021r ; 4.55879e-308 +$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 @@ -3333,15 +3488,18 @@ $chain$1$stbi__zbuild_huffman DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__zbuild_huffman DQ 00020640800020821r ; 4.55883e-308 +$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 DQ 00018011100072319r ; 3.33819e-308 - DQ 050057006e008f00ar ; 3.10288e+77 +$unwind$stbi__zbuild_huffman DD 072319H + DD 0180111H + DD 0e008f00aH + DD 050057006H DD 03004H DD imagerel __GSHandlerCheck DD 0b0H @@ -3355,14 +3513,16 @@ $chain$1$stbi__zreceive DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__zreceive DQ 00002340500020521r ; 3.06393e-309 +$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 DQ 00000700200010201r ; 6.08461e-310 +$unwind$stbi__zreceive DD 010201H + DD 07002H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3373,44 +3533,53 @@ $chain$1$stbi__zhuffman_decode DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__zhuffman_decode DQ 00006340500020521r ; 8.62661e-309 +$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 DQ 07002320600020601r ; 3.53109e+231 +$unwind$stbi__zhuffman_decode DD 020601H + DD 070023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__zexpand DQ 00006640000020021r ; 8.88726e-309 +$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 DQ 00006640500020521r ; 8.88736e-309 +$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 DQ 00007340a00040a01r ; 1.00174e-308 +$unwind$stbi__zexpand DD 040a01H + DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__parse_huffman_block DQ 00008e42b000c2b01r ; 1.23648e-308 - DQ 0000a5418000b6418r ; 1.43635e-308 - DQ 0f014321800093418r ; -7.83854e+231 +$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 DQ 0014c740000040021r ; 2.07455e-302 +$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 @@ -3418,7 +3587,8 @@ $chain$3$stbi__compute_huffman_codes DQ 0014c740000040021r ; 2.07455e-302 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__compute_huffman_codes DQ 0014b649b00049b21r ; 1.99726e-302 +$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 @@ -3426,50 +3596,63 @@ $chain$2$stbi__compute_huffman_codes DQ 0014b649b00049b21r ; 1.99726e-302 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__compute_huffman_codes DQ 0014de40800020821r ; 2.17937e-302 +$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 DQ 00144011000072219r ; 1.45853e-302 - DQ 05003c005d007f009r ; 2.85863e+77 +$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 DQ 00007340a00040a01r ; 1.00174e-308 +$unwind$stbi__parse_uncompressed_block DD 040a01H + DD 07340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__parse_zlib DQ 00008741500081501r ; 1.1756e-308 - DQ 00006341500076415r ; 8.62695e-309 +$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 DQ 00207011200062419r ; 6.87007e-299 - DQ 03002500360047005r ; 1.97688e-77 +$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 DQ 00007640f00060f01r ; 1.02782e-308 - DQ 0700b320f0006340fr ; 5.2777e+231 +$unwind$stbi__get_chunk_header DD 060f01H + DD 07640fH + DD 06340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__check_png_header DQ 00007640f00060f01r ; 1.02782e-308 - DQ 0700b320f0006340fr ; 5.2777e+231 +$unwind$stbi__check_png_header DD 060f01H + DD 07640fH + DD 06340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__paeth DQ 00001340500020501r ; 1.67326e-309 +$unwind$stbi__paeth DD 020501H + DD 013405H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3480,7 +3663,8 @@ $chain$3$stbi__create_png_image_raw DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__create_png_image_raw DQ 0001fd40000020021r ; 4.42625e-308 +$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 @@ -3494,28 +3678,35 @@ $chain$1$stbi__create_png_image_raw DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__create_png_image_raw DQ 0001fd40800020821r ; 4.42626e-308 +$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 DQ 00016011600091601r ; 3.06007e-308 - DQ 07009c00be00df00fr ; 4.9972e+231 - DQ 00000300650076008r ; 2.60885e-310 +$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 DQ 00023640000020021r ; 5.3932e-308 +$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 DQ 00021f40000060021r ; 4.99338e-308 - DQ 0002364000022d400r ; 5.3932e-308 +$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 @@ -3529,7 +3720,8 @@ $chain$3$stbi__create_png_image DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__create_png_image DQ 00021f41300041321r ; 4.99346e-308 +$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 @@ -3537,22 +3729,28 @@ $chain$2$stbi__create_png_image DQ 00021f41300041321r ; 4.99346e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__create_png_image DQ 00023640800020821r ; 5.39323e-308 +$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 DQ 00024012200072201r ; 5.56392e-308 - DQ 050167017c019e01br ; 6.49532e+77 +$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 DQ 0000a6418000a1801r ; 1.44505e-308 - DQ 00008341800095418r ; 1.14084e-308 - DQ 07010e012f0143218r ; 6.5498e+231 +$unwind$stbi__expand_png_palette DD 0a1801H + DD 0a6418H + DD 095418H + DD 083418H + DD 0f0143218H + DD 07010e012H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3563,51 +3761,65 @@ $chain$1$stbi__de_iphone DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__de_iphone DQ 00000340400020421r ; 2.82565e-310 +$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 DQ 00000020400010401r ; 1.09495e-311 +$unwind$stbi__de_iphone DD 010401H + DD 0204H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__parse_png_file DQ 0029b742d000d3e19r ; 4.19785e-296 - DQ 00299342d029a642dr ; 3.85381e-296 - DQ 0e016f0180292012dr ; -7.68866e+154 - DQ 000005010c012d014r ; 4.3494e-310 +$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 DQ 0000d741e000c1e01r ; 1.87095e-308 - DQ 0000b541e000c641er ; 1.57543e-308 - DQ 0f01a521e000a341er ; -1.02159e+232 +$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 DQ 0f009c20d00071c19r ; -4.99872e+231 - DQ 0500360047005e007r ; 2.80435e+77 +$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 DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__png_test DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__bmp_test_raw DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__bmp_test_raw DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__bmp_test DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__bmp_test DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata @@ -3619,8 +3831,10 @@ $chain$6$stbi__bmp_parse_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__bmp_parse_header DQ 0000af40000060021r ; 1.52322e-308 - DQ 0000854000009e400r ; 1.15817e-308 +$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 @@ -3634,14 +3848,16 @@ $chain$3$stbi__bmp_parse_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__bmp_parse_header DQ 00009e40500020521r ; 1.37547e-308 +$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 DQ 0000af40d00040d21r ; 1.52325e-308 +$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 @@ -3649,14 +3865,18 @@ $chain$1$stbi__bmp_parse_header DQ 0000af40d00040d21r ; 1.52325e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__bmp_parse_header DQ 07004320800040801r ; 3.91922e+231 +$unwind$stbi__bmp_parse_header DD 040801H + DD 070043208H DD 030026003H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__bmp_load DQ 000a43426000b2601r ; 1.43855e-305 - DQ 0e01df01f009c0126r ; -1.00351e+155 - DQ 060167017c019d01br ; 7.52106e+154 +$unwind$stbi__bmp_load DD 0b2601H + DD 0a43426H + DD 09c0126H + DD 0e01df01fH + DD 0c019d01bH + DD 060167017H DD 05015H xdata ENDS ; COMDAT xdata @@ -3668,61 +3888,78 @@ $chain$3$stbi__tga_test DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__tga_test DQ 0000af40500020521r ; 1.52323e-308 +$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 DQ 00009645100085101r ; 1.3061e-308 - DQ 0e00532090008544cr ; -3.55231e+154 +$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 DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__tga_read_rgb16 DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__tga_load DQ 000130114000a2619r ; 2.64286e-308 - DQ 0c007d009e00bf00dr ; -2.97658 - DQ 03002500360047005r ; 1.97688e-77 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__psd_test DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__psd_decode_rle DQ 0000b741e000c1e01r ; 1.59282e-308 - DQ 00009541e000a641er ; 1.2973e-308 - DQ 0f01a321e0008341er ; -1.01674e+232 +$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 DQ 0000e640000020021r ; 2.00126e-308 +$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 DQ 0000af40000060021r ; 1.52322e-308 - DQ 0000e6400000be400r ; 2.00126e-308 +$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 DQ 0000af400000c0021r ; 1.52322e-308 - DQ 0000cd400000be400r ; 1.78397e-308 - DQ 0000e6400000dc400r ; 2.00126e-308 +$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 @@ -3744,14 +3981,16 @@ $chain$6$stbi__psd_load DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__psd_load DQ 0000cd40500020521r ; 1.78398e-308 +$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 DQ 0000dc41400041421r ; 1.91439e-308 +$chain$4$stbi__psd_load DD 041421H + DD 0dc414H DD 0125408H DD imagerel stbi__psd_load+157 DD imagerel stbi__psd_load+924 @@ -3759,40 +3998,54 @@ $chain$4$stbi__psd_load DQ 0000dc41400041421r ; 1.91439e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__psd_load DQ 0000af46500066521r ; 1.52343e-308 - DQ 0000e6405000be45dr ; 2.00127e-308 +$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 DQ 07011e21500031501r ; 6.94097e+231 +$unwind$stbi__psd_load DD 031501H + DD 07011e215H DD 03010H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__pic_is4 DQ 00007640f00060f01r ; 1.02782e-308 - DQ 0700b320f0006340fr ; 5.2777e+231 +$unwind$stbi__pic_is4 DD 060f01H + DD 07640fH + DD 06340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__pic_test_core DQ 00008641400081401r ; 1.1669e-308 - DQ 00006341400075414r ; 8.62693e-309 +$unwind$stbi__pic_test_core DD 081401H + DD 086414H + DD 075414H + DD 063414H DD 070103214H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__readval DQ 00009741a000a1a01r ; 1.31467e-308 - DQ 00007541a0008641ar ; 1.01916e-308 - DQ 0e016321a0006341ar ; -7.4399e+154 +$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 DQ 000106452000d5219r ; 2.27957e-308 - DQ 0001a343200115441r ; 3.6441e-308 - DQ 0e00af00c00120113r ; -4.51469e+154 - DQ 000007004c006d008r ; 6.08519e-310 +$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 @@ -3805,7 +4058,8 @@ $chain$2$stbi__pic_load DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$1$stbi__pic_load DQ 0000be40d00040d21r ; 1.65362e-308 +$chain$1$stbi__pic_load DD 040d21H + DD 0be40dH DD 0c5405H DD imagerel stbi__pic_load DD imagerel stbi__pic_load+353 @@ -3813,8 +4067,10 @@ $chain$1$stbi__pic_load DQ 0000be40d00040d21r ; 1.65362e-308 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__pic_load DQ 0f00ac20e00071d19r ; -5.19279e+231 - DQ 060037004c006d008r ; 3.25769e+154 +$unwind$stbi__pic_load DD 071d19H + DD 0f00ac20eH + DD 0c006d008H + DD 060037004H DD 03002H DD imagerel __GSHandlerCheck DD 040H @@ -3828,25 +4084,31 @@ $chain$3$stbi__pic_test DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__pic_test DQ 00008641400061421r ; 1.1669e-308 - DQ 000097405000ac40fr ; 1.31463e-308 +$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 DQ 0000b340e00060e01r ; 1.55802e-308 - DQ 05006e008f00a320er ; 3.31095e+77 +$unwind$stbi__pic_test DD 060e01H + DD 0b340eH + DD 0f00a320eH + DD 05006e008H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__gif_test_raw DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__gif_test_raw DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__gif_test DQ 03002320600020601r ; 1.96423e-77 +$unwind$stbi__gif_test DD 020601H + DD 030023206H xdata ENDS ; COMDAT xdata xdata SEGMENT @@ -3857,15 +4119,18 @@ $chain$1$stbi__gif_parse_colortable DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__gif_parse_colortable DQ 00008740500020521r ; 1.17556e-308 +$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 DQ 0000a541c00081c01r ; 1.43636e-308 - DQ 0f018321c0009341cr ; -9.39108e+231 +$unwind$stbi__gif_parse_colortable DD 081c01H + DD 0a541cH + DD 09341cH + DD 0f018321cH DD 06014e016H xdata ENDS ; COMDAT xdata @@ -3877,7 +4142,8 @@ $chain$3$stbi__gif_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$2$stbi__gif_header DQ 00006e40000020021r ; 9.58259e-309 +$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 @@ -3891,27 +4157,34 @@ $chain$1$stbi__gif_header DD 021H xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$0$stbi__gif_header DQ 00006e40500020521r ; 9.5827e-309 +$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 DQ 00009741500081501r ; 1.31466e-308 - DQ 00007341500086415r ; 1.00176e-308 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__out_gif_code DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$7$stbi__process_gif_raster DQ 00006f400000c0021r ; 9.66951e-309 - DQ 00008c4000007e400r ; 1.21901e-308 - DQ 0000a640000097400r ; 1.44499e-308 +$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 @@ -3919,9 +4192,12 @@ $chain$7$stbi__process_gif_raster DQ 00006f400000c0021r ; 9.66951e-309 xdata ENDS ; COMDAT xdata xdata SEGMENT -$chain$5$stbi__process_gif_raster DQ 00006f444000c4421r ; 9.67095e-309 - DQ 00008c4310007e438r ; 1.21911e-308 - DQ 0000a641600097425r ; 1.44504e-308 +$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 @@ -3929,85 +4205,103602 @@ $chain$5$stbi__process_gif_raster DQ 00006f444000c4421r ; 9.67095e-309 xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__process_gif_raster DQ 0d004a20800030801r ; -2.98641e+77 +$unwind$stbi__process_gif_raster DD 030801H + DD 0d004a208H DD 03002H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__gif_load_next DQ 0000c6421000c2101r ; 1.7232e-308 - DQ 0000a3421000b5421r ; 1.41899e-308 - DQ 0d019e01bf01d3221r ; -7.49042e+77 +$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 DQ 01117011600082819r ; 2.42768e-226 - DQ 060047005e007f009r ; 3.42529e+154 +$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 DQ 00007640f00060f01r ; 1.02782e-308 - DQ 0700b320f0006340fr ; 5.2777e+231 +$unwind$stbi__hdr_test_core DD 060f01H + DD 07640fH + DD 06340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__hdr_test DQ 00008741500081501r ; 1.1756e-308 - DQ 00006341500076415r ; 8.62695e-309 +$unwind$stbi__hdr_test DD 081501H + DD 087415H + DD 076415H + DD 063415H DD 0e0113215H xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__hdr_gettoken DQ 0000a6418000a1801r ; 1.44505e-308 - DQ 00008341800095418r ; 1.14084e-308 - DQ 07010e012f0143218r ; 6.5498e+231 +$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 DQ 00007640f00060f01r ; 1.02782e-308 - DQ 0700b320f0006340fr ; 5.2777e+231 +$unwind$stbi__hdr_convert DD 060f01H + DD 07640fH + DD 06340fH + DD 0700b320fH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__hdr_load DQ 0008f011c000a2d19r ; 5.51895e-306 - DQ 0c007d009e00bf00dr ; -2.97658 - DQ 05002300360047005r ; 2.63247e+77 +$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 DQ 00006340a00040a01r ; 8.62672e-309 +$unwind$stbi__pnm_test DD 040a01H + DD 06340aH DD 07006320aH xdata ENDS ; COMDAT xdata xdata SEGMENT -$unwind$stbi__pnm_load DQ 0000d741e000c1e01r ; 1.87095e-308 - DQ 0000b541e000c641er ; 1.57543e-308 - DQ 0f01a521e000a341er ; -1.02159e+232 +$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 DQ 0000b741e000c1e01r ; 1.59282e-308 - DQ 00009541e000a641er ; 1.2973e-308 - DQ 0f01a321e0008341er ; -1.01674e+232 +$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 DQ 0000b741e000c1e01r ; 1.59282e-308 - DQ 00009541e000a641er ; 1.2973e-308 - DQ 0f01a321e0008341er ; -1.01674e+232 +$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 DQ 0f009620d00071c19r ; -4.92595e+231 - DQ 0500360047005e007r ; 2.80435e+77 +$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 diff --git a/æº�代ç �/StgSharpC/x64/Release/stb_image.obj b/æº�代ç �/StgSharpC/x64/Release/stb_image.obj index 465112a5..2b6fd2ba 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/stb_image.obj and b/æº�代ç �/StgSharpC/x64/Release/stb_image.obj differ diff --git a/æº�代ç �/StgSharpC/x64/Release/vc143.pdb b/æº�代ç �/StgSharpC/x64/Release/vc143.pdb index 638cb87f..315e840b 100644 Binary files a/æº�代ç �/StgSharpC/x64/Release/vc143.pdb and b/æº�代ç �/StgSharpC/x64/Release/vc143.pdb differ diff --git a/æº�代ç �/StgSharpC/x64/Release/vector.cod b/æº�代ç �/StgSharpC/x64/Release/vector.cod new file mode 100644 index 00000000..7613b98b --- /dev/null +++ b/æº�代ç �/StgSharpC/x64/Release/vector.cod @@ -0,0 +1,108 @@ +; Listing generated by Microsoft (R) Optimizing Compiler Version 19.39.33523.0 + +include listing.inc + +INCLUDELIB OLDNAMES + +PUBLIC normalize +; Function compile flags: /Ogtpy +; File D:\NitloadIndustry\Ñо¿ÏîÄ¿\1-Flagship\TH2020\ProjectFile\Ô´´úÂë\StgSharpC\vector.c +; COMDAT normalize +_TEXT SEGMENT +source$ = 8 +target$ = 16 +normalize PROC ; COMDAT + +; 6 : // ¼ÆËãsourceµÄ³¤¶ÈµÄƽ·½ +; 7 : __m128 a_length_sq = _mm_mul_ps(*source, *source); // ÏòÁ¿µã³Ë×ÔÉí + + 00000 0f 10 11 movups xmm2, XMMWORD PTR [rcx] + 00003 0f 28 ca movaps xmm1, xmm2 + 00006 0f 59 ca mulps xmm1, xmm2 + +; 8 : a_length_sq = _mm_add_ps(a_length_sq, _mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(2, 3, 0, 1))); + + 00009 0f 28 c1 movaps xmm0, xmm1 + 0000c 0f c6 c1 b1 shufps xmm0, xmm1, 177 ; 000000b1H + 00010 0f 58 c8 addps xmm1, xmm0 + +; 9 : a_length_sq = _mm_add_ss(a_length_sq, _mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(0, 0, 3, 2))); + + 00013 0f 28 c1 movaps xmm0, xmm1 + 00016 0f c6 c1 0e shufps xmm0, xmm1, 14 + 0001a f3 0f 58 c8 addss xmm1, xmm0 + +; 10 : +; 11 : // ¹éÒ»»¯ÏòÁ¿source +; 12 : __m128 a_inv_length = _mm_rsqrt_ps(a_length_sq); // ¼ÆËãsource³¤¶ÈµÄµ¹Êýƽ·½¸ù + + 0001e 0f 52 d9 rsqrtps xmm3, xmm1 + +; 13 : *source = _mm_mul_ps(*source, a_inv_length); // ÓÃsource³ËÒÔÆä³¤¶ÈµÄµ¹Êýƽ·½¸ùµÃµ½µ¥Î»ÏòÁ¿ + + 00021 0f 59 da mulps xmm3, xmm2 + 00024 0f 11 19 movups XMMWORD PTR [rcx], xmm3 + +; 14 : +; 15 : // ¼ÆËãtargetÓësourceµÄµã»ý +; 16 : __m128 dot_product = _mm_mul_ps(*target, *source); + + 00027 0f 28 cb movaps xmm1, xmm3 + 0002a 0f 10 12 movups xmm2, XMMWORD PTR [rdx] + 0002d 0f 59 ca mulps xmm1, xmm2 + +; 17 : dot_product = _mm_add_ps(dot_product, _mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(2, 3, 0, 1))); + + 00030 0f 28 c1 movaps xmm0, xmm1 + 00033 0f c6 c1 b1 shufps xmm0, xmm1, 177 ; 000000b1H + 00037 0f 58 c8 addps xmm1, xmm0 + +; 18 : dot_product = _mm_add_ss(dot_product, _mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(0, 0, 3, 2))); + + 0003a 0f 28 c1 movaps xmm0, xmm1 + 0003d 0f c6 c1 0e shufps xmm0, xmm1, 14 + 00041 f3 0f 58 c8 addss xmm1, xmm0 + +; 19 : +; 20 : // ´ÓtargetÖмõÈ¥sourceµÄ·½Ïò·ÖÁ¿£¬Ê¹Æä´¹Ö±ÓÚsource +; 21 : __m128 b_orthogonal = _mm_sub_ps(*target, _mm_mul_ps(*source, dot_product)); + + 00045 0f 59 cb mulps xmm1, xmm3 + 00048 0f 5c d1 subps xmm2, xmm1 + +; 22 : +; 23 : // ¹éÒ»»¯ÏòÁ¿b_orthogonal +; 24 : __m128 b_length_sq = _mm_mul_ps(b_orthogonal, b_orthogonal); + + 0004b 0f 28 ca movaps xmm1, xmm2 + 0004e 0f 59 ca mulps xmm1, xmm2 + +; 25 : b_length_sq = _mm_add_ps(b_length_sq, _mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(2, 3, 0, 1))); + + 00051 0f 28 c1 movaps xmm0, xmm1 + 00054 0f c6 c1 b1 shufps xmm0, xmm1, 177 ; 000000b1H + 00058 0f 58 c8 addps xmm1, xmm0 + +; 26 : b_length_sq = _mm_add_ss(b_length_sq, _mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(0, 0, 3, 2))); + + 0005b 0f 28 c1 movaps xmm0, xmm1 + 0005e 0f c6 c1 0e shufps xmm0, xmm1, 14 + 00062 f3 0f 58 c8 addss xmm1, xmm0 + +; 27 : +; 28 : __m128 b_inv_length = _mm_rsqrt_ps(b_length_sq); + + 00066 0f 52 c9 rsqrtps xmm1, xmm1 + +; 29 : *target = _mm_mul_ps(b_orthogonal, b_inv_length); + + 00069 0f 59 ca mulps xmm1, xmm2 + 0006c 0f 11 0a movups XMMWORD PTR [rdx], xmm1 + +; 30 : +; 31 : } + + 0006f c3 ret 0 +normalize ENDP +_TEXT ENDS +END diff --git a/æº�代ç �/StgSharpC/x64/Release/vector.obj b/æº�代ç �/StgSharpC/x64/Release/vector.obj new file mode 100644 index 00000000..7d4bd389 Binary files /dev/null and b/æº�代ç �/StgSharpC/x64/Release/vector.obj differ diff --git a/æº�代ç �/StgSharpDebug/Program.cs b/æº�代ç �/StgSharpDebug/Program.cs index 23f0ce55..c49423c5 100644 --- a/æº�代ç �/StgSharpDebug/Program.cs +++ b/æº�代ç �/StgSharpDebug/Program.cs @@ -70,10 +70,10 @@ namespace StgSharp 0.0f, 0.5f, 0.0f ); Rectangle rec = new Rectangle( - -0.75f, 0.75f, 0.0f, - 0.75f, 0.75f, 0.0f, - 0.75f, -0.75f, 0.0f, - -0.75f, -0.75f, 0.0f + -0.3f, 0.3f, 0.0f, + 0.3f, 0.3f, 0.0f, + 0.3f, -0.3f, 0.0f, + -0.3f, -0.3f, 0.0f ); Polygon5 polygon = new Polygon5( -0.4f, 0.5f, 0.0f, @@ -121,12 +121,20 @@ namespace StgSharp /**/ camera = new Camera( - new vec3d(0,0,1.0f), + new vec3d(1,1,1), new vec3d(0,0,0), new vec3d(0,1,0) ); - camera.Perspective(new Radius(Scaler.Pi / 3),this.Size,0.5f,-0.5f); - camera.GainAllUniforms(shader, "projection", "lookAt"); + camera.SetViewRange(new Radius(Scaler.Pi / 2),this.Size,(0,0),(1f,1f)); + camera.GainAllUniforms(shader, "camera"); + /**/ + camera.Test( + new vec4d(0.5f,0.5f,0, 1), + new vec4d(0.5f, -0.5f, 0, 1), + new vec4d(-0.5f, -0.5f, 0, 1), + new vec4d(-0.5f, 0.5f, 0, 1) + ); + /**/ } protected override void Main() @@ -149,6 +157,12 @@ namespace StgSharp /**/ float time = CurrentFrameCount / 60.0f; + camera.SetViewDirection( + new vec3d(Scaler.Cos(time * 10), 1, Scaler.Sin(time * 10)), + new vec3d(0, 0, 0), + new vec3d(0, 1, 0) + ); + GL.SetValue(color, 0.5f + MathF.Cos(time), 0.5f + MathF.Sin(time * 0.66667f + 2 * Scaler.Pi / 3), diff --git a/æº�代ç �/StgSharpDebug/Shader/vertex.vert b/æº�代ç �/StgSharpDebug/Shader/vertex.vert index 7fefa48c..d3050afe 100644 --- a/æº�代ç �/StgSharpDebug/Shader/vertex.vert +++ b/æº�代ç �/StgSharpDebug/Shader/vertex.vert @@ -8,8 +8,7 @@ out vec4 TexColor; out vec2 TexCoord; uniform vec4 color; -uniform mat4x4 lookAt; -uniform mat4x4 projection; +uniform mat4x4 camera; void main() { @@ -21,10 +20,10 @@ void main() 0,0,1,0, 0,0,0,1 ); - vec4 temp = (vec4(aPos.xyz,1.0) + vec4(color.yz-vec2(0.5,0.5),0.0,0.0)) * rotation; - gl_Position = projection * lookAt * temp; TexColor = color; TexCoord = aTextCoord; + vec4 temp = (vec4(aPos.xyz,1.0) + vec4(color.yz-vec2(0.5,0.5),0.0,0.0)) * rotation; + gl_Position = /**/ camera * /**/ temp; } //struct diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfo.cs b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfo.cs index 7ac3edcf..670e3a33 100644 --- a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfo.cs +++ b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+127fcdbfd32fd1caa4a55ced77c7e738f038a59c")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache index de230686..3dabc306 100644 --- a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache +++ b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache @@ -1 +1 @@ -404eed79c64e05ccd057bd69d0503642dcf7340a381bfbf7fcd452b46996af31 +5fc65e27ab1eae6b9eeb60c61c388d2d98eeb396f53cbb6b719f6e99588e5cd4 diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.dll b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.dll index fe1104c5..0d6d2699 100644 Binary files a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.dll and b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.dll differ diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.pdb b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.pdb index 5aa4b2c5..2ed8405d 100644 Binary files a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.pdb and b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.pdb differ diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.sourcelink.json b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.sourcelink.json index 7a2e3d97..3d27e0be 100644 --- a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.sourcelink.json +++ b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.sourcelink.json @@ -1 +1 @@ -{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/127fcdbfd32fd1caa4a55ced77c7e738f038a59c/*"}} \ No newline at end of file +{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1/*"}} \ No newline at end of file diff --git a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.xml b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.xml index 313cf22e..08e8e6fb 100644 --- a/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.xml +++ b/æº�代ç �/StgSharpDebug/obj/x64/Debug/net6.0/StgSharpDebug.xml @@ -64,12 +64,12 @@ Set all necessary metadata to current form instance
- + Resize the current form - A (width,height) representing the new size of current form + A (width,height) representing the new size of current form @@ -79,15 +79,15 @@ New width of the window New height of the window - + Set the size limit of current form - Minimun size of current form. In form of a of (width,height) + Minimun size of current form. In form of a of (width,height) - Maximum size of current form. In form of a of (width,height) + Maximum size of current form. In form of a of (width,height) @@ -412,7 +412,7 @@ An IEEE-754 double precision floating-point value, clamped to the range [0,1].
- + A two dimension vector defined by two elements. Vec2Ds in StgSharp are defaultly usaed as colum vector. diff --git a/�代�/StgSharpDebug/obj/x64/Debug/net6.0/apphost.exe b/�代�/StgSharpDebug/obj/x64/Debug/net6.0/apphost.exe index 2eefd6f3..5f012d06 100644 Binary files a/�代�/StgSharpDebug/obj/x64/Debug/net6.0/apphost.exe and b/�代�/StgSharpDebug/obj/x64/Debug/net6.0/apphost.exe differ diff --git a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfo.cs b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfo.cs index 8d1c6c69..7a821b3b 100644 --- a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfo.cs +++ b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("RealDebug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyTitleAttribute("StgSharpDebug")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache index 12f6dd5a..96a3d11f 100644 --- a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache +++ b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.AssemblyInfoInputs.cache @@ -1 +1 @@ -89486dc671b7ac4f5d315ed89aaca21b3f7af7896e6ac4f4e417616c97a6421c +2f4c77bd1fc4272d4cf4b3aa0bb67811f058b4248c7ce85863503cb47703efd4 diff --git a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.GeneratedMSBuildEditorConfig.editorconfig b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.GeneratedMSBuildEditorConfig.editorconfig index 006ce8af..1e50f4ef 100644 --- a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.GeneratedMSBuildEditorConfig.editorconfig +++ b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.GeneratedMSBuildEditorConfig.editorconfig @@ -1,4 +1,6 @@ is_global = true +build_property.CsWin32InputMetadataPaths = C:\Users\Nitlo\.nuget\packages\microsoft.windows.sdk.win32metadata\55.0.45-preview\Windows.Win32.winmd|C:\Users\Nitlo\.nuget\packages\microsoft.windows.wdk.win32metadata\0.9.9-experimental\Windows.Wdk.winmd +build_property.CsWin32InputDocPaths = C:\Users\Nitlo\.nuget\packages\microsoft.windows.sdk.win32docs\0.1.42-alpha\apidocs.msgpack build_property.TargetFramework = net6.0 build_property.TargetPlatformMinVersion = build_property.UsingMicrosoftNETSdkWeb = diff --git a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.assets.cache b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.assets.cache index e48243a3..e3d29ae2 100644 Binary files a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.assets.cache and b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/StgSharpDebug.assets.cache differ diff --git a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/apphost.exe b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/apphost.exe index bb29fa59..0d34725d 100644 Binary files a/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/apphost.exe and b/�代�/StgSharpDebug/obj/x64/RealDebug/net6.0/apphost.exe differ diff --git a/�代�/StgsharpEnvDebug/Program.cs b/�代�/StgsharpEnvDebug/Program.cs index 2d9e1590..3d99ca25 100644 --- a/�代�/StgsharpEnvDebug/Program.cs +++ b/�代�/StgsharpEnvDebug/Program.cs @@ -1,5 +1,6 @@ using StgSharp; using StgSharp.Graphics; +using StgSharp.Math; namespace StgsharpEnvDebug { @@ -7,7 +8,20 @@ namespace StgsharpEnvDebug { static void Main(string[] args) { - Console.WriteLine("Hello, World!"); + Matrix44 m1 = new Matrix44( + 0, 1, 2, 3, + 4,5,6,7, + 8,9,10,11, + 12,13,14,15 + ); + Matrix44 m2 = new Matrix44( + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15 + ); + + Console.WriteLine(m1*m2); } } diff --git a/�代�/StgsharpEnvDebug/StgsharpEnvDebug.csproj b/�代�/StgsharpEnvDebug/StgsharpEnvDebug.csproj index 6654c812..783f1bd4 100644 --- a/�代�/StgsharpEnvDebug/StgsharpEnvDebug.csproj +++ b/�代�/StgsharpEnvDebug/StgsharpEnvDebug.csproj @@ -13,4 +13,8 @@ + + + + diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.dll b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.dll new file mode 100644 index 00000000..3f496187 Binary files /dev/null and b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.dll differ diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.xml b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.xml new file mode 100644 index 00000000..13be4ca9 --- /dev/null +++ b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharp.xml @@ -0,0 +1,1865 @@ + + + + StgSharp + + + + + Get the status of a certain key on the keyboard. + + + + + + + + Function handler to load an opengl function by serching its name. + + the name of the Opengl function + An intptr value representing the pointer to the function + + + + + + + + + Height of this form, represent in + + + + + Width of this form, represent in + + + + + Width of this form, represent in + + + + + Necessary operation to init graphic elements this form. + + OpenGL library binded to current form. + + + + Behaviour of current form when in a frame cycle. + + + + + Init an OpenGl context if current form has not been binded to any context. and set the context binded to + current form as current OpenGL context. + + + Something goes wrong and StgSharp fails in creating a new OpenGL context. + + + + + Set all necessary metadata to current form instance + + + + + Resize the current form + + + A (width,height) representing the new size of current form + + + + + Resize the current form + + New width of the window + New height of the window + + + + Set the size limit of current form + + + Minimun size of current form. In form of a of (width,height) + + + Maximum size of current form. In form of a of (width,height) + + + + + Set the size limit of current form + + Minimum width of current form + Minimum height of current form + Maximum width of current form + Maximum height of current form + + + + Init this form and render it on screen, and respond with operation + + + + + Create a set of . + + Amount of EBO to be created. + + + + + Create a sets of + + Amount of textures to be crated. + + + + + Create a set of . + + Amount of VAO to be crated. + + + + + Create aset of . + + Amount of Object to be created. + + + + + Create an instance of program + + New instance of instance. + + + + Mark that a method in a + should be called when rendering. + + + + + Priority level of a render activity. + + + + + One level higher than . + + + + + Two level higher than . + + + + + Three level higher than . + + + + + One level lower than . + + + + + Two level lower than . + + + + + Three level lower than . + + + + + Highest priority, in , it is . + + + + + Default priority, usually is in this priority. + + + + + Lowest priority, in , it is . + + + + + Interface of all kinds OpenGL buffer objects + + + + + Get the only handle to one of the Object instance + + + + + + + Bind a buffer instance to OpenGL + + Index of handle of the object in this instance to be bind + + + + + + + A collecion of handle to Element Buffer Object in OpenGL. + Each value indexed from instance of this class this + is the only handle to one Element Buffer Object. + + + + + + + + + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + Data to write in + How OpenGL use these data, defined by + + + + Set data to current vertex buffer object + + Type of bufferData + Index to find certain VBO in this instance + A array of data to write in + How OpenGL use these data, defined by + + + + + + + + + Load all aupportable OpenGL APIs and bind them to given context. + + The used as current OpenGL context + A delegate to get address of OprnGL api + + + + Get the function pointer of given OpenGL api name + + Name of the OpenGL api + The funtion pointer of the api in form of + + + + A handle to an OpenGL object, + must be indexed from a . + Direct call will cause + + + + + A handle to an OpenGL object. + + + + + Release all resource in this handle. + This will release all resource in this . + This will be not usable. + + + + + + + + + + + + + + + + + + + + + + + + + + Attach one shader code to a shader program. + + Shader program to attach + Index of shader code in current shader code set. + + + + Init a program with no shader attached. + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Get a uniform form current shader, + the value type of the uniform should be provided. + + Name of the Uniform in shader code + + + + + Link the shader to current context. + + + + + Let the current context use this shader. + + + + + A sensor used for cheking out if a bullet hit a player or something else + + + + + A 2D vector presenting the position of an enemy entity, position can also be visited by X, Y + + + + + X position of an enenmy entity + + + + + Y position of an enemy entity + + + + + Init an instance of OpenGL program, + This method should be called before any other StgSharp api. + + + + + Version of current StgSharp platform. + Main version represent in hundred's digit, + and sub version represent in ten's digit. + + + + + Write a log message to log file, and mark the level of this message. + + A string contains information of how current evironment runs. + The severity of current message. + + + + OpenGL numeric type. + An IEEE-754 floating-point value, clamped to the range [0,1]. + + + + + OpenGL numeric type. + An IEEE-754 double precision floating-point value, clamped to the range [0,1]. + + + + + A two dimension vector defined by two elements. + Vec2Ds in StgSharp are defaultly usaed as colum vector. + + + + + Reurns the value of ArcSin(x) + + The sine value of the angle + + + + + + Get the value of E ^ x; + + + + + + + + + + + Returns the value of ln(x). + + + + + calculate the value of x^y + + + + Returns the value of x^y + + + + returns a random float number between 0 and 1. + + + + + + + + + + + + Generates a random seed in int value. + + + + + + Part of a circle. All points on a arc has the same distance to their center. + + + + + A collection of all point on the same plain and has the same distance to a point + + + + + The origin of this coordinate. + + + + + The horizontial axis of the coordinate. + Point to the right direction. + + + + + The vertical axis of the coordinate. + Point to the top direction. + + + + + 当几何体调用了过多的CalcVec方法时,产生UnusedVertexException异常 + + + + + Caculate the movement of a point. + + The game tick represent time passed by + A 3d vector representing movement + + + + Move begin side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + + Move end side of a line. + It is recommended to override this function rather than + loading an with same function. + + Time passed since current line was created. + + + + + Move the third vertix. this is a useless method for Parallelograms. + + Current time tick + + Geometry overdefined + + + + Move the third vertix. This method is useless for Parallelograms. + + Current time tick + + Geometry overdefined + + + + 平�几何体。包�三角形,对称四边形,自由多边形等。最多�由16个点�数定义。 + + + + + Tick time this geometry eas crested + + + + + Get all sides of this . + + A array contains all straight s of current geometry item. + + + + Get a flat cincide with current geometry. + + + + + + Update the coordinate of the point. If this is a moving point, + (Points on sides or surface if other geometry items) + please do not define any motion here, codes will be ignored by program + + Time passes since the program begin, counted by frames + + + + 计算中心点相对于�考原点的�移 + + 当�游�刻 + + + + + A square + + + + + A linear data structure with dynamic length. + It contains a of , + each is twice longer than the former one. + + + + + + Init a with a certain amount of elements prepared. + + Amount of elements to be prepared. + + + + Create a new instance of , + and fill the begining ones of elemtns as given instance. + + Amount of beginning elements to be filled + + + + + Length of this + + + + + A pair of value + + + + + The first value. + + + + + The second value. + + + + + A value. + The lower byte is , + and higher byte is . + + + + + A microsecond-accuracy timer. It will refresh every a certain time span. + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Create a new and define the length of time span. + Length of a single time span is defined in seconds. + + + + + + + Create a new and define the length of time span. Length of a single time span is defined in microseconds. + + + + + + + Time source provider provided in internal framework. + + + + + The method this will call every time a new time span started. + + + + + Get all uniform related to this . + + Shader program requires this camera. + + Name of all related uniforms. + If you fallow form from + + + + + The COLORREF value is used to specify an RGB color. + + When specifying an explicit [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) color, the **COLORREF** value has the following hexadecimal form: `0x00bbggrr` The low-order byte contains a value for the relative intensity of red; the second byte contains a value for green; and the third byte contains a value for blue. The high-order byte must be zero. The maximum value for a single byte is 0xFF. To create a **COLORREF** color value, use the [RGB](/windows/desktop/api/Wingdi/nf-wingdi-rgb) macro. To extract the individual values for the red, green, and blue components of a color value, use the [**GetRValue**](/windows/desktop/api/Wingdi/nf-wingdi-getrvalue), [GetGValue](/windows/desktop/api/Wingdi/nf-wingdi-getgvalue), and [GetBValue](/windows/desktop/api/Wingdi/nf-wingdi-getbvalue) macros, respectively. + Read more on docs.microsoft.com. + + + + + A pointer to a null-terminated, constant, ANSI character string. + + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, decoding as UTF-8. + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + + A pointer to a null-terminated, constant character string. + + + + + A pointer to the first character in the string. The content should be considered readonly, as it was typed as constant in the SDK. + + + + + Gets the number of characters up to the first null character (exclusive). + + + + + Returns a with a copy of this character array, up to the first null character (exclusive). + + A , or if is . + + + + Returns a span of the characters in this string, up to the first null character (exclusive). + + + + The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners. + The RECT structure is identical to the RECTL structure. + + + Specifies the x-coordinate of the upper-left corner of the rectangle. + + + Specifies the y-coordinate of the upper-left corner of the rectangle. + + + Specifies the x-coordinate of the lower-right corner of the rectangle. + + + Specifies the y-coordinate of the lower-right corner of the rectangle. + + + Contains message information from a thread's message queue. + + Learn more about this API from docs.microsoft.com. + + + + + Type: HWND A handle to the window whose window procedure receives the message. This member is NULL when the message is a thread message. + Read more on docs.microsoft.com. + + + + + Type: UINT The message identifier. Applications can only use the low word; the high word is reserved by the system. + Read more on docs.microsoft.com. + + + + + Type: WPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: LPARAM Additional information about the message. The exact meaning depends on the value of the message member. + Read more on docs.microsoft.com. + + + + + Type: DWORD The time at which the message was posted. + Read more on docs.microsoft.com. + + + + + Type: POINT The cursor position, in screen coordinates, when the message was posted. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (ANSI) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + Contains the window class attributes that are registered by the RegisterClass function. (Unicode) + + > [!NOTE] > The winuser.h header defines WNDCLASS as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + + Type: UINT The class style(s). This member can be any combination of the Class Styles. + Read more on docs.microsoft.com. + + + + + Type: WNDPROC A pointer to the window procedure. You must use the CallWindowProc function to call the window procedure. For more information, see WindowProc. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window-class structure. The system initializes the bytes to zero. + Read more on docs.microsoft.com. + + + + + Type: int The number of extra bytes to allocate following the window instance. The system initializes the bytes to zero. If an application uses WNDCLASS to register a dialog box created by using the CLASS directive in the resource file, it must set this member to DLGWINDOWEXTRA. + Read more on docs.microsoft.com. + + + + + Type: HINSTANCE A handle to the instance that contains the window procedure for the class. + Read more on docs.microsoft.com. + + + + + Type: HICON A handle to the class icon. This member must be a handle to an icon resource. If this member is NULL, the system provides a default icon. + Read more on docs.microsoft.com. + + + + + Type: HCURSOR A handle to the class cursor. This member must be a handle to a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window. + Read more on docs.microsoft.com. + + + + + Type: HBRUSH A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the following HBRUSH types: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR The resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu. + Read more on docs.microsoft.com. + + + + + Type: LPCTSTR A pointer to a null-terminated string or is an atom. If this parameter is an atom, it must be a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpszClassName; the high-order word must be zero. + If lpszClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names. The maximum length for lpszClassName is 256. If lpszClassName is greater than the maximum length, the RegisterClass function will fail. + Read more on docs.microsoft.com. + + + + + Represents a Win32 handle that can be closed with . + + + + + Represents a Win32 handle that can be closed with . + + + + The GLYPHMETRICSFLOAT structure contains information about the placement and orientation of a glyph in a character cell. + The values of GLYPHMETRICSFLOAT are specified as notional units. + + + Specifies the width of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the height of the smallest rectangle (the glyph's black box) that completely encloses the glyph. + + + Specifies the x and y coordinates of the upper-left corner of the smallest rectangle that completely encloses the glyph. + + + Specifies the horizontal distance from the origin of the current character cell to the origin of the next character cell. + + + Specifies the vertical distance from the origin of the current character cell to the origin of the next character cell. + + + The LAYERPLANEDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice, as documented above, that certain layer plane properties are not supported in the current implementation. The implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers that enhance parts of OpenGL may support some layer plane properties not supported by the generic implementation. + + + Specifies the size of this data structure. Set this value to sizeof(LAYERPLANEDESCRIPTOR). + + + Specifies the version of this data structure. Set this value to 1. + + + + A set of bit flags that specify properties of the layer plane. The properties are generally not mutually exclusive; any combination of bit flags can be set, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + + + + Not used. Must be zero. + + + When the LPD_TRANSPARENT flag is set, specifies the transparent color or index value. Typically the value is zero. + + + The PIXELFORMATDESCRIPTOR structure describes the pixel format of a drawing surface. + Please notice carefully, as documented above, that certain pixel format properties are not supported in the current generic implementation. The generic implementation is the Microsoft GDI software implementation of OpenGL. Hardware manufacturers may enhance parts of OpenGL, and may support some pixel format properties not supported by the generic implementation. + + + Specifies the size of this data structure. This value should be set to sizeof(PIXELFORMATDESCRIPTOR). + + + Specifies the version of this data structure. This value should be set to 1. + + + + A set of bit flags that specify properties of the pixel buffer. The properties are generally not mutually exclusive; you can set any combination of bit flags, with the exceptions noted. The following bit flag constants are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + Specifies the type of pixel data. The following types are defined. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Specifies the number of color bitplanes in each color buffer. For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes. For color-index pixels, it is the size of the color-index buffer. + + + Specifies the number of red bitplanes in each RGBA color buffer. + + + Specifies the shift count for red bitplanes in each RGBA color buffer. + + + Specifies the number of green bitplanes in each RGBA color buffer. + + + Specifies the shift count for green bitplanes in each RGBA color buffer. + + + Specifies the number of blue bitplanes in each RGBA color buffer. + + + Specifies the shift count for blue bitplanes in each RGBA color buffer. + + + Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported. + + + Specifies the total number of bitplanes in the accumulation buffer. + + + Specifies the number of red bitplanes in the accumulation buffer. + + + Specifies the number of green bitplanes in the accumulation buffer. + + + Specifies the number of blue bitplanes in the accumulation buffer. + + + Specifies the number of alpha bitplanes in the accumulation buffer. + + + Specifies the depth of the depth (z-axis) buffer. + + + Specifies the depth of the stencil buffer. + + + Specifies the number of auxiliary buffers. Auxiliary buffers are not supported. + + + Specifies the number of overlay and underlay planes. Bits 0 through 3 specify up to 15 overlay planes and bits 4 through 7 specify up to 15 underlay planes. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + Specifies the transparent color or index of an underlay plane. When the pixel type is RGBA, dwVisibleMask is a transparent RGB color value. When the pixel type is color index, it is a transparent index value. + + + Ignored. Earlier implementations of OpenGL used this member, but it is no longer used. + + + The POINTFLOAT structure contains the x and y coordinates of a point. + + Learn more about this API from docs.microsoft.com. + + + + Specifies the horizontal (x) coordinate of a point. + + + Specifies the vertical (y) coordinate of a point. + + + + Contains extern methods from "GDI32.dll". + + + Contains extern methods from "KERNEL32.dll". + + + Contains extern methods from "OPENGL32.dll". + + + Contains extern methods from "USER32.dll". + + + + The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the specified handle is no longer valid. + A handle to a logical pen, brush, font, bitmap, region, or palette. + + If the function succeeds, the return value is nonzero. If the specified handle is not valid or is currently selected into a DC, the return value is zero. + + + Do not delete a drawing object (pen or brush) while it is still selected into a DC. When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently. + Read more on docs.microsoft.com. + + + + + + + The ChoosePixelFormat function attempts to match an appropriate pixel format supported by a device context to a given pixel format specification. + Specifies the device context that the function examines to determine the best match for the pixel format descriptor pointed to by ppfd. + + Pointer to a PIXELFORMATDESCRIPTOR structure that specifies the requested pixel format. In this context, the members of the PIXELFORMATDESCRIPTOR structure that ppfd points to are used as follows: + This doc was truncated. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a pixel format index (one-based) that is the closest match to the given pixel format descriptor. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + You must ensure that the pixel format matched by the ChoosePixelFormat function satisfies your requirements. For example, if you request a pixel format with a 24-bit RGB color buffer but the device context offers only 8-bit RGB color buffers, the function returns a pixel format with an 8-bit RGB color buffer. + + + The DescribePixelFormat function obtains information about the pixel format identified by iPixelFormat of the device associated with hdc. The function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd with that pixel format data. + Specifies the device context. + Index that specifies the pixel format. The pixel formats that a device context supports are identified by positive one-based integer indexes. + The size, in bytes, of the structure pointed to by ppfd. The DescribePixelFormat function stores no more than nBytes bytes of data to that structure. Set this value to sizeof(PIXELFORMATDESCRIPTOR). + Pointer to a PIXELFORMATDESCRIPTOR structure whose members the function sets with pixel format data. The function stores the number of bytes copied to the structure in the structure's nSize member. If, upon entry, ppfd is NULL, the function writes no data to the structure. This is useful when you only want to obtain the maximum pixel format index of a device context. + + If the function succeeds, the return value is the maximum pixel format index of the device context. In addition, the function sets the members of the PIXELFORMATDESCRIPTOR structure pointed to by ppfd according to the specified pixel format. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + The DeleteEnhMetaFile function deletes an enhanced-format metafile or an enhanced-format metafile handle. + A handle to an enhanced metafile. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + If the hemf parameter identifies an enhanced metafile stored in memory, the DeleteEnhMetaFile function deletes the metafile. If hemf identifies a metafile stored on a disk, the function deletes the metafile handle but does not destroy the actual metafile. An application can retrieve the file by calling the GetEnhMetaFile function. + + + + + + The GetEnhMetaFilePixelFormat function retrieves pixel format information for an enhanced metafile. + Identifies the enhanced metafile. + Specifies the size, in bytes, of the buffer into which the pixel format information is copied. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The metafile uses this structure to record the logical pixel format specification. + + If the function succeeds and finds a pixel format, the return value is the size of the metafile's pixel format. If no pixel format is present, the return value is zero. If an error occurs and the function fails, the return value is GDI_ERROR. To get extended error information, call GetLastError. + + + When an enhanced metafile specifies a pixel format in its ENHMETAHEADER structure and the pixel format fits in the buffer, the pixel format information is copied into ppfd. When cbBuffer is too small to contain the pixel format of the metafile, the pixel format is not copied to the buffer. In either case, the function returns the size of the metafile's pixel format. For information on metafile recording and other operations, see Enhanced Metafile Operations. + Read more on docs.microsoft.com. + + + + The GetPixelFormat function obtains the index of the currently selected pixel format of the specified device context. + Specifies the device context of the currently selected pixel format index returned by the function. + + If the function succeeds, the return value is the currently selected pixel format index of the specified device context. This is a positive, one-based index value. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Learn more about this API from docs.microsoft.com. + + + + + + + The SetPixelFormat function sets the pixel format of the specified device context to the format specified by the iPixelFormat index. + Specifies the device context whose pixel format the function attempts to set. + Index that identifies the pixel format to set. The various pixel formats supported by a device context are identified by one-based indexes. + Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The system's metafile component uses this structure to record the logical pixel format specification. The structure has no other effect upon the behavior of the SetPixelFormat function. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If hdc references a window, calling the SetPixelFormat function also changes the pixel format of the window. Setting the pixel format of a window more than once can lead to significant complications for the Window Manager and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a window's pixel format is set, it cannot be changed. You should select a pixel format in the device context before calling the wglCreateContext function. The wglCreateContext function creates a rendering context for drawing on the device in the selected pixel format of the device context. An OpenGL window has its own pixel format. Because of this, only device contexts retrieved for the client area of an OpenGL window are allowed to draw into the window. As a result, an OpenGL window should be created with the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles. Additionally, the window class attribute should not include the CS_PARENTDC style. + Read more on docs.microsoft.com. + + + + The SwapBuffers function exchanges the front and back buffers if the current pixel format for the window referenced by the specified device context includes a back buffer. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + If the current pixel format for the window referenced by the device context does not include a back buffer, this call has no effect and the content of the back buffer is undefined when the function returns. With multithread applications, flush the drawing commands in any other threads drawing to the same window before calling SwapBuffers. + Read more on docs.microsoft.com. + + + + Closes an open object handle. + A valid handle to an open object. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle returned by the FindFirstFile function instead of calling the FindClose function. + + + The CloseHandle function closes handles to the following objects: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. + + A handle to the loaded library module. The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call the GetLastError function. + + + The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file. The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process. It is not safe to call FreeLibrary from DllMain. For more information, see the Remarks section in DllMain. Calling FreeLibrary does not affect other processes that are using the same module. Use caution when calling FreeLibrary with a handle returned by GetModuleHandle. The GetModuleHandle function does not increment a module's reference count, so passing this handle to FreeLibrary can cause a module to be unloaded prematurely. A thread that must unload the DLL in which it is executing and then terminate itself should call FreeLibraryAndExitThread instead of calling FreeLibrary and ExitThread separately. Otherwise, a race condition can occur. For details, see the Remarks section of FreeLibraryAndExitThread. + Read more on docs.microsoft.com. + + + + + + + Retrieves a module handle for the specified module. The module must have been loaded by the calling process. (Unicode) + + The name of the loaded module (either a .dll or .exe file). If the file name extension is omitted, the default library extension .dll is appended. The file name string can include a trailing point character (.) to indicate that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process. + If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file). The GetModuleHandle function does not retrieve handles for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the specified module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The returned handle is not global or inheritable. It cannot be duplicated or used by another process. If lpModuleName does not include a path and there is more than one loaded module with the same base name and extension, you cannot predict which module handle will be returned. To work around this problem, you could specify a path, use side-by-side assemblies, or use GetModuleHandleEx to specify a memory location rather than a DLL name. The GetModuleHandle function returns a handle to a mapped module without incrementing its reference count. However, if this handle is passed to the FreeLibrary function, the reference count of the mapped module will be decremented. Therefore, do not pass a handle returned by GetModuleHandle to the FreeLibrary function. Doing so can cause a DLL module to be unmapped prematurely. This function must be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used. For example, suppose that a thread retrieves a module handle, but before it uses the handle, a second thread frees the module. If the system loads another module, it could reuse the module handle that was recently freed. Therefore, the first thread would have a handle to a different module than the one intended. + Read more on docs.microsoft.com. + + + + + + + Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). + + A handle to the DLL module that contains the function or variable. The LoadLibrary, LoadLibraryEx, LoadPackagedLibrary, or GetModuleHandle function returns this handle. The GetProcAddress function does not retrieve addresses from modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. + Read more on docs.microsoft.com. + + The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero. + + If the function succeeds, the return value is the address of the exported function or variable. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The spelling and case of a function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.def) file. The exported names of functions may differ from the names you use when calling these functions in your code. This difference is hidden by macros used in the SDK header files. For more information, see Conventions for Function Prototypes. The lpProcName parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the .def file. The function then uses the ordinal as an index to read the function's address from a function table. If the .def file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress returns an invalid, non-NULL address, even though there is no function with the specified ordinal. If the function might not exist in the DLL module—for example, if the function is available only on Windows Vista but the application might be running on Windows XP—specify the function by name rather than by ordinal value and design your application to handle the case when the function is not available, as shown in the following code fragment. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Loads the specified module into the address space of the calling process. (LoadLibraryW) + + The name of the module. This can be either a library module (a .dll file) or an executable module (an .exe file). If the specified module is an executable module, static imports are not loaded; instead, the module is loaded as if by LoadLibraryEx with the `DONT_RESOLVE_DLL_REFERENCES` flag. The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file. If the string specifies a full path, the function searches only that path for the module. If the string specifies a relative path or a module name without a path, the function uses a standard search strategy to find the module; for more information, see the Remarks. If the function cannot find the module, the function fails. When specifying a path, be sure to use backslashes (\\), not forward slashes (/). For more information about paths, see Naming a File or Directory. If the string specifies a module name without a path and the file name extension is omitted, the function appends the default library extension ".DLL" to the module name. To prevent the function from appending ".DLL" to the module name, include a trailing point character (.) in the module name string. + Read more on docs.microsoft.com. + + + If the function succeeds, the return value is a handle to the module. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function. LoadLibrary can be used to load a library module into the address space of the process and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to load other executable modules. For example, the function can specify an .exe file to get a handle that can be used in FindResource or LoadResource. However, do not use LoadLibrary to run an .exe file. Instead, use the CreateProcess function. If the specified module is a DLL that is not already loaded for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If DllMain returns TRUE, LoadLibrary returns a handle to the module. If DllMain returns FALSE, the system unloads the DLL from the process address space and LoadLibrary returns NULL. It is not safe to call LoadLibrary from DllMain. For more information, see the Remarks section in DllMain. Module handles are not global or inheritable. A call to LoadLibrary by one process does not produce a handle that another process can use — for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress. If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first. If no file name extension is specified in the lpFileName parameter, the default library extension .dll is appended. However, the file name string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file. The first directory searched is the directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable. If a relative path is specified, the entire relative path is appended to every token in the DLL search path list. To load a module from a relative path without searching any other path, use GetFullPathName to get a nonrelative path and call LoadLibrary with the nonrelative path. For more information on the DLL search order, see Dynamic-Link Library Search Order. The search path can be altered using the SetDllDirectory function. This solution is recommended instead of using SetCurrentDirectory or hard-coding the full path to the DLL. If a path is specified and there is a redirection file for the application, the function searches for the module in the application's directory. If the module exists in the application's directory, LoadLibrary ignores the specified path and loads the module from the application's directory. If the module does not exist in the application's directory, LoadLibrary loads the module from the specified directory. For more information, see Dynamic Link Library Redirection. If you call LoadLibrary with the name of an assembly without a path specification and the assembly is listed in the system compatible manifest, the call is automatically redirected to the side-by-side assembly. The system maintains a per-process reference count on all loaded modules. Calling LoadLibrary increments the reference count. Calling the FreeLibrary or FreeLibraryAndExitThread function decrements the reference count. The system unloads a module when its reference count reaches zero or when the process terminates (regardless of the reference count). Windows Server 2003 and Windows XP:  The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary on versions of Windows prior to Windows Vista. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread). For an example, see Using Thread Local Storage in a Dynamic Link Library.

Security Remarks

Do not use the SearchPath function to retrieve a path to a DLL for a subsequent LoadLibrary call. The SearchPath function uses a different search order than LoadLibrary and it does not use safe process search mode unless this is explicitly enabled by calling SetSearchPathMode with BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Therefore, SearchPath is likely to first search the user’s current working directory for the specified DLL. If an attacker has copied a malicious version of a DLL into the current working directory, the path retrieved by SearchPath will point to the malicious DLL, which LoadLibrary will then load. Do not make assumptions about the operating system version based on a LoadLibrary call that searches for a DLL. If the application is running in an environment where the DLL is legitimately not present but a malicious version of the DLL is in the search path, the malicious version of the DLL may be loaded. Instead, use the recommended techniques described in Getting the System Version.
+ Read more on docs.microsoft.com. +
+
+ + + + + The wglGetProcAddress function returns the address of an OpenGL extension function for use with the current OpenGL rendering context. + + When the function succeeds, the return value is the address of the extension function. When no current rendering context exists or the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The OpenGL library supports multiple implementations of its functions. Extension functions supported in one rendering context are not necessarily available in a separate rendering context. Thus, for a given rendering context in an application, use the function addresses returned by the wglGetProcAddress function only. The spelling and the case of the extension function pointed to by lpszProc must be identical to that of a function supported and implemented by OpenGL. Because extension functions are not exported by OpenGL, you must use wglGetProcAddress to get the addresses of vendor-specific extension functions. The extension function addresses are unique for each pixel format. All rendering contexts of a given pixel format share the same extension function addresses. + Read more on docs.microsoft.com. + + + + The wglDeleteContext function deletes a specified OpenGL rendering context. + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + It is an error to delete an OpenGL rendering context that is the current context of another thread. However, if a rendering context is the calling thread's current context, the wglDeleteContext function changes the rendering context to being not current before deleting it. The wglDeleteContext function does not delete the device context associated with the OpenGL rendering context when you call the wglMakeCurrent function. After calling wglDeleteContext, you must call DeleteDC to delete the associated device context. + Read more on docs.microsoft.com. + + + + + + + The wglCreateContext function creates a new OpenGL rendering context, which is suitable for drawing on the device referenced by hdc. The rendering context has the same pixel format as the device context. + + If the function succeeds, the return value is a valid handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is not the same as a device context. Set the pixel format of the device context before creating a rendering context. For more information on setting the device context's pixel format, see the SetPixelFormat function. To use OpenGL, you create a rendering context, select it as a thread's current rendering context, and then call OpenGL functions. When you are finished with the rendering context, you dispose of it by calling the wglDeleteContext function. The following code example shows wglCreateContext usage. + + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglCreateLayerContext function creates a new OpenGL rendering context for drawing to a specified layer plane on a device context. + + If the function succeeds, the return value is a handle to an OpenGL rendering context. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + A rendering context is a port through which all OpenGL commands pass. Every thread that makes OpenGL calls must have one current, active rendering context. A rendering context is not the same as a device context; a rendering context contains information specific to OpenGL, while a device context contains information specific to GDI. Before you create a rendering context, set the pixel format of the device context with the SetPixelFormat function. You can use a rendering context in a specified layer plane of a window with identical pixel formats only. With OpenGL applications that use multiple threads, you create a rendering context, select it as the current rendering context of a thread, and make OpenGL calls for the specified thread. When you are finished with the rendering context of the thread, call the wglDeleteContext function. + Read more on docs.microsoft.com. + + + + + + + The wglCopyContext function copies selected groups of rendering states from one OpenGL rendering context to another. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + Using the wglCopyContext function, you can synchronize the rendering state of two rendering contexts. You can only copy the rendering state between two rendering contexts within the same process. The rendering contexts must be from the same OpenGL implementation. For example, you can always copy a rendering state between two rendering contexts with identical pixel format in the same process. You can copy the same state information available only with the glPushAttrib function. You cannot copy some state information, such as pixel pack/unpack state, render mode state, select state, and feedback state. When you call wglCopyContext, make sure that the destination rendering context, hglrcDst, is not current to any thread. + Read more on docs.microsoft.com. + + + + + + + The wglDescribeLayerPlane function obtains information about the layer planes of a given pixel format. + + If the function succeeds, the return value is TRUE. In addition, the wglDescribeLayerPlane function sets the members of the LAYERPLANEDESCRIPTOR structure pointed to by plpd according to the specified layer plane (iLayerPlane ) of the specified pixel format (iPixelFormat ). If the function fails, the return value is FALSE. + + The numbering of planes (iLayerPlane ) determines their order. Higher-numbered planes overlay lower-numbered planes. + + + + + + The wglGetCurrentContext function obtains a handle to the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, wglGetCurrentContext returns a handle to that rendering context. Otherwise, the return value is NULL. + The current OpenGL rendering context of a thread is associated with a device context by means of the wglMakeCurrent function. You can use the wglGetCurrentDC function to obtain a handle to the device context associated with the current OpenGL rendering context. + + + The wglGetCurrentDC function obtains a handle to the device context that is associated with the current OpenGL rendering context of the calling thread. + If the calling thread has a current OpenGL rendering context, the function returns a handle to the device context associated with that rendering context by means of the wglMakeCurrent function. Otherwise, the return value is NULL. + You associate a device context with an OpenGL rendering context when it calls the wglMakeCurrent function. You can use the wglGetCurrentContext function to obtain a handle to the calling thread's current OpenGL rendering context. + + + + + + Retrieves the palette entries from a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or when no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index layer plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. + Read more on docs.microsoft.com. + + + + + + + The wglMakeCurrent function makes a specified OpenGL rendering context the calling thread's current rendering context. + When the wglMakeCurrent function succeeds, the return value is TRUE; otherwise the return value is FALSE. To get extended error information, call GetLastError. + + The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format. GDI transformation and clipping in hdc are not supported by the rendering context. The current rendering context uses the hdc device context until the rendering context is no longer current. Before switching to the new rendering context, OpenGL flushes any previous rendering context that was current to the calling thread. A thread can have one current rendering context. A process can have multiple rendering contexts by means of multithreading. A thread must set a current rendering context before calling any OpenGL functions. Otherwise, all OpenGL calls are ignored. A rendering context can be current to only one thread at a time. You cannot make a rendering context current to multiple threads. An application can perform multithread drawing by making different rendering contexts current to different threads, supplying each thread with its own rendering context and device context. If an error occurs, the wglMakeCurrent function makes the thread's current rendering context not current before returning. + Read more on docs.microsoft.com. + + + + The wglRealizeLayerPalette function maps palette entries from a given color-index layer plane into the physical palette or initializes the palette of an RGBA layer plane. + If the function succeeds, the return value is TRUE, even if bRealize is TRUE and the physical palette is not available. If the function fails or when no pixel format is selected, the return value is FALSE. To get extended error information, call GetLastError. + + The physical palette for a layer plane is a shared resource among windows with layer planes. When more than one window attempts to realize a palette for a given physical layer plane, only one palette at a time is realized. When you call the wglRealizeLayerPalette function, the layer palette of a foreground window is always realized first. When a window's layer palette is realized, its palette entries are always mapped one-to-one into the physical palette. Unlike GDI logical palettes, with wglRealizeLayerPalette there is no mapping of other windows' layer palettes to the current physical palette. Whenever a window becomes the foreground window, call wglRealizeLayerPalette to realize its layer palettes again, even if the pixel type of the layer plane is RGBA. Because wglRealizeLayerPalette doesn't realize the palette of the main plane, use GDI palette functions to realize the main plane palette. + Read more on docs.microsoft.com. + + + + + + + Sets the palette entries in a given color-index layer plane for a specified device context. + + Type: int If the function succeeds, the return value is the number of entries that were set in the palette in the specified layer plane of the window. If the function fails or no pixel format is selected, the return value is zero. To get extended error information, call GetLastError. + + + Each color-index plane in a window has a palette with a size 2^n, where n is the number of bit planes in the layer plane. You cannot modify the transparent index of a palette. Use the wglRealizeLayerPalette function to realize the layer palette. Initially the layer palette contains only entries for white. The wglSetLayerPaletteEntries function doesn't set the palette entries of the main plane palette. To update the main plane palette, use GDI palette functions. + Read more on docs.microsoft.com. + + + + + + + The wglShareLists function enables multiple OpenGL rendering contexts to share a single display-list space. + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and the display lists are not shared. To get extended error information, call GetLastError. + + + When you create an OpenGL rendering context, it has its own display-list space. The wglShareLists function enables a rendering context to share the display-list space of another rendering context; any number of rendering contexts can share a single display-list space. Once a rendering context shares a display-list space, the rendering context always uses the display-list space until the rendering context is deleted. When the last rendering context of a shared display-list space is deleted, the shared display-list space is deleted. All the indexes and definitions of display lists in a shared display-list space are shared. You can only share display lists with rendering contexts within the same process. However, not all rendering contexts in a process can share display lists. Rendering contexts can share display lists only if they use the same implementation of OpenGL functions. All client rendering contexts of a given pixel format can always share display lists. All rendering contexts of a shared display list must use an identical pixel format. Otherwise the results depend on the implementation of OpenGL used.
Note  The wglShareLists function is only available with OpenGL version 1.01 or later. To determine the version number of the implementation of OpenGL, call glGetString.
 
+ Read more on docs.microsoft.com. +
+
+ + The wglSwapLayerBuffers function swaps the front and back buffers in the overlay, underlay, and main planes of the window referenced by a specified device context. + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + When a layer plane doesn't include a back buffer, calling the wglSwapLayerBuffers function has no effect on that layer plane. After you call wglSwapLayerBuffers, the state of the back buffer content is given in the corresponding LAYERPLANEDESCRIPTOR structure of the layer plane or in the PIXELFORMATDESCRIPTOR structure of the main plane. The wglSwapLayerBuffers function swaps the front and back buffers in the specified layer planes simultaneously. Some devices don't support swapping layer planes individually; they swap all layer planes as a group. When the PFD_SWAP_LAYER_BUFFERS flag of the PIXELFORMATDESCRIPTOR structure is set, it indicates that a device can swap individual layer planes and that you can call wglSwapLayerBuffers. With applications that use multiple threads, before calling wglSwapLayerBuffers, clear all drawing commands in all threads drawing to the same window. + Read more on docs.microsoft.com. + + + + The wglUseFontBitmaps function creates a set of bitmap display lists for use in the current OpenGL rendering context. (Unicode) + + If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError. + + + The wglUseFontBitmaps function defines count display lists in the current OpenGL rendering context. Each display list has an identifying number, starting at listBase. Each display list consists of a single call to glBitmap. The definition of bitmap listBase + i is taken from the glyph first + i of the font currently selected in the device context specified by hdc. If a glyph is not defined, then the function defines an empty display list for it. The wglUseFontBitmaps function creates bitmap text in the plane of the screen. It enables the labeling of objects in OpenGL. In the current version of Microsoft's implementation of OpenGL, you cannot make GDI calls to a device context that has a double-buffered pixel format. Therefore, you cannot use the GDI fonts and text functions with such device contexts. You can use the wglUseFontBitmaps function to circumvent this limitation and draw text in a double-buffered device context. The function determines the parameters of each call to glBitmap as follows. + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + The wglUseFontOutlines function creates a set of display lists, one for each glyph of the currently selected outline font of a device context, for use with the current rendering context. (Unicode) + + When the function succeeds, the return value is TRUE. When the function fails, the return value is FALSE and no display lists are generated. To get extended error information, call GetLastError. + + + The wglUseFontOutlines function defines the glyphs of an outline font with display lists in the current rendering context. The wglUseFontOutlines function works with TrueType fonts only; stroke and raster fonts are not supported. Each display list consists of either line segments or polygons, and has a unique identifying number starting with the listBase number. The wglUseFontOutlines function approximates glyph outlines by subdividing the quadratic B-spline curves of the outline into line segments, until the distance between the outline and the interpolated midpoint is within the value specified by deviation. This is the final format used when format is WGL_FONT_LINES. When you specify WGL_FONT_OUTLINES, the display lists created don't contain any normals; thus lighting doesn't work properly. To get the correct lighting of lines use WGL_FONT_POLYGONS and set glPolygonMode( GL_FRONT, GL_LINE ). When you specify format as WGL_FONT_POLYGONS the outlines are further tessellated into separate triangles, triangle fans, triangle strips, or quadrilateral strips to create the surface of each glyph. With WGL_FONT_POLYGONS, the created display lists call glFrontFace( GL_CW ) or glFrontFace( GL_CCW ); thus the current front-face value might be altered. For the best appearance of text with WGL_FONT_POLYGONS, cull the back faces as follows: + + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys an icon and frees any memory the icon occupied. + + Type: HICON A handle to the icon to be destroyed. The icon must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + It is only necessary to call DestroyIcon for icons and cursors created with the following functions: CreateIconFromResourceEx (if called without the LR_SHARED flag), CreateIconIndirect, and CopyIcon. Do not use this function to destroy a shared icon. A shared icon is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared icon. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Destroys a cursor and frees any memory the cursor occupied. Do not use this function to destroy a shared cursor. + + Type: HCURSOR A handle to the cursor to be destroyed. The cursor must not be in use. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + The DestroyCursor function destroys a nonshared cursor. Do not use this function to destroy a shared cursor. A shared cursor is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared cursor: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Calculates the required size of the window rectangle, based on the desired client-rectangle size. The window rectangle can then be passed to the CreateWindow function to create a window whose client area is the desired size. + + Type: LPRECT A pointer to a RECT structure that contains the coordinates of the top-left and bottom-right corners of the desired client area. When the function returns, the structure contains the coordinates of the top-left and bottom-right corners of the window to accommodate the desired client area. + Read more on docs.microsoft.com. + + + Type: DWORD The window style of the window whose required size is to be calculated. Note that you cannot specify the WS_OVERLAPPED style. + Read more on docs.microsoft.com. + + + Type: BOOL Indicates whether the window has a menu. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A client rectangle is the smallest rectangle that completely encloses a client area. A window rectangle is the smallest rectangle that completely encloses the window, which includes the client area and the nonclient area. The AdjustWindowRect function does not add extra space when a menu bar wraps to two or more rows. The AdjustWindowRect function does not take the WS_VSCROLL or WS_HSCROLL styles into account. To account for the scroll bars, call the GetSystemMetrics function with SM_CXVSCROLL or SM_CYHSCROLL. + Read more on docs.microsoft.com. + + + + Destroys the specified menu and frees any memory that the menu occupies. + + Type: HMENU A handle to the menu to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + Before closing, an application must use the DestroyMenu function to destroy a menu not assigned to a window. A menu that is assigned to a window is automatically destroyed when the application closes. DestroyMenu is recursive, that is, it will destroy the menu and all its submenus. + Read more on docs.microsoft.com. + + + + + + + Creates an overlapped, pop-up, or child window with an extended window style; otherwise, this function is identical to the CreateWindow function. (Unicode) + + Type: DWORD The extended window style of the window being created. For a list of possible values, see Extended Window Styles. + Read more on docs.microsoft.com. + + + Type: LPCTSTR A null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax "#num". + Read more on docs.microsoft.com. + + + Type: DWORD The style of the window being created. This parameter can be a combination of the window style values, plus the control styles indicated in the Remarks section. + Read more on docs.microsoft.com. + + + Type: int The initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If x is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero. + Read more on docs.microsoft.com. + + + Type: int The initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area. + If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter. + Read more on docs.microsoft.com. + + + Type: int The width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinates to the right edge of the screen; the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameter are set to zero. + Read more on docs.microsoft.com. + + + Type: int The height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows. To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window. + Read more on docs.microsoft.com. + + + Type: HMENU A handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window. + Read more on docs.microsoft.com. + + + Type: HINSTANCE A handle to the instance of the module to be associated with the window. + Read more on docs.microsoft.com. + + + Type: LPVOID Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns. If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed. + Read more on docs.microsoft.com. + + + Type: HWND If the function succeeds, the return value is a handle to the new window. If the function fails, the return value is NULL. To get extended error information, call GetLastError. This function typically fails for one of the following reasons: + This doc was truncated. + + + The CreateWindowEx function sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created. If the created window is a child window, its default position is at the bottom of the Z-order. If the created window is a top-level window, its default position is at the top of the Z-order (but beneath all topmost windows unless the created window is itself topmost). For information on controlling whether the Taskbar displays a button for the created window, see Managing Taskbar Buttons. For information on removing a window, see the DestroyWindow function. The following predefined control classes can be specified in the lpClassName parameter. Note the corresponding control styles you can use in the dwStyle parameter. + This doc was truncated. + Read more on docs.microsoft.com. + + + + Calls the default window procedure to provide default processing for any window messages that an application does not process. (Unicode) + + Type: HWND A handle to the window procedure that received the message. + Read more on docs.microsoft.com. + + + Type: UINT The message. + Read more on docs.microsoft.com. + + + Type: WPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LPARAM Additional message information. The content of this parameter depends on the value of the Msg parameter. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value is the result of the message processing and depends on the message. + + + > [!NOTE] > The winuser.h header defines DefWindowProc as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see [Conventions for Function Prototypes](/windows/win32/intl/conventions-for-function-prototypes). + Read more on docs.microsoft.com. + + + + Destroys the specified window. + + Type: HWND A handle to the window to be destroyed. + Read more on docs.microsoft.com. + + + Type: BOOL If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + A thread cannot use DestroyWindow to destroy a window created by a different thread. If the window being destroyed is a child window that does not have the WS_EX_NOPARENTNOTIFY style, a WM_PARENTNOTIFY message is sent to the parent. + Read more on docs.microsoft.com. + + + + + + + Dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage function. (DispatchMessageW) + + Type: const MSG* A pointer to a structure that contains the message. + Read more on docs.microsoft.com. + + + Type: LRESULT The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored. + + + The MSG structure must contain valid message values. If the lpmsg parameter points to a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The GetDC function retrieves a handle to a device context (DC) for the client area of a specified window or for the entire screen. + A handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen. + + If the function succeeds, the return value is a handle to the DC for the specified window's client area. If the function fails, the return value is NULL. + + + The GetDC function retrieves a common, class, or private DC depending on the class style of the specified window. For class and private DCs, GetDC leaves the previously assigned attributes unchanged. However, for common DCs, GetDC assigns default attributes to the DC each time it is retrieved. For example, the default font is System, which is a bitmap font. Because of this, the handle to a common DC returned by GetDC does not tell you what font, color, or brush was used when the window was drawn. To determine the font, call GetTextFace. Note that the handle to the DC can only be used by a single thread at any one time. After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. ReleaseDC must be called from the same thread that called GetDC. The number of DCs is limited only by available memory. + Read more on docs.microsoft.com. + + + + + + + Loads the specified cursor resource from the executable (.EXE) file associated with an application instance. (Unicode) + + Type: HINSTANCE A handle to an instance of the module whose executable file contains the cursor to be loaded. + Read more on docs.microsoft.com. + + + Type: LPCTSTR The name of the cursor resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. The MAKEINTRESOURCE macro can also be used to create this value. To use one of the predefined cursors, the application must set the hInstance parameter to NULL and the lpCursorName parameter to one the following values. + This doc was truncated. + Read more on docs.microsoft.com. + + + Type: HCURSOR If the function succeeds, the return value is the handle to the newly loaded cursor. If the function fails, the return value is NULL. To get extended error information, call GetLastError. + + + The LoadCursor function loads the cursor resource only if it has not been loaded; otherwise, it retrieves the handle to the existing resource. This function returns a valid cursor handle only if the lpCursorName parameter is a pointer to a cursor resource. If lpCursorName is a pointer to any type of resource other than a cursor (such as an icon), the return value is not NULL, even though it is not a valid cursor handle. The LoadCursor function searches the cursor resource most appropriate for the cursor for the current display device. The cursor resource can be a color or monochrome bitmap.

DPI Virtualization

This API does not participate in DPI virtualization. The output returned is not affected by the DPI of the calling thread.
+ Read more on docs.microsoft.com. +
+
+ + + + + Dispatches incoming nonqueued messages, checks the thread message queue for a posted message, and retrieves the message (if any exist). (Unicode) + + Type: LPMSG A pointer to an MSG structure that receives message information. + Read more on docs.microsoft.com. + + + Type: HWND A handle to the window whose messages are to be retrieved. The window must belong to the current thread. + If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed. If hWnd is -1, PeekMessage retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage. + Read more on docs.microsoft.com. + + + Type: UINT The value of the first message in the range of messages to be examined. Use WM_KEYFIRST (0x0100) to specify the first keyboard message or WM_MOUSEFIRST (0x0200) to specify the first mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + + Type: UINT The value of the last message in the range of messages to be examined. Use WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to specify the last mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed). + Read more on docs.microsoft.com. + + Type: UINT + + Type: BOOL If a message is available, the return value is nonzero. If no messages are available, the return value is zero. + + + PeekMessage retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function, and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax parameters; the high word is reserved for the system. Note that PeekMessage always retrieves WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax. During this call, the system dispatches (DispatchMessage) pending, nonqueued messages, that is, messages sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that matches the specified filter is retrieved. The system may also process internal events. If no filter is specified, messages are processed in the following order: + This doc was truncated. + Read more on docs.microsoft.com. + + + + Indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. + + Type: int The application exit code. This value is used as the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future. When the thread retrieves the WM_QUIT message from its message queue, it should exit its message loop and return control to the system. The exit value returned to the system must be the wParam parameter of the WM_QUIT message. + Read more on docs.microsoft.com. + + + + Registers a window class for subsequent use in calls to the CreateWindow or CreateWindowEx function. (RegisterClassW) + + Type: const WNDCLASS* A pointer to a WNDCLASS structure. You must fill the structure with the appropriate class attributes before passing it to the function. + Read more on docs.microsoft.com. + + + Type: ATOM If the function succeeds, the return value is a class atom that uniquely identifies the class being registered. This atom can only be used by the CreateWindow, CreateWindowEx, GetClassInfo, GetClassInfoEx, FindWindow, FindWindowEx, and UnregisterClass functions and the IActiveIMMap::FilterClientWindows method. If the function fails, the return value is zero. To get extended error information, call GetLastError. + + + If you register the window class by using RegisterClassA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterClassW, the application requests that the system pass text parameters of messages as Unicode. The IsWindowUnicode function enables applications to query the nature of each window. For more information on ANSI and Unicode functions, see Conventions for Function Prototypes. All window classes that an application registers are unregistered when it terminates. No window classes registered by a DLL are unregistered when the DLL is unloaded. A DLL must explicitly unregister its classes when it is unloaded. + Read more on docs.microsoft.com. + + + + The ReleaseDC function releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. It has no effect on class or private DCs. + A handle to the window whose DC is to be released. + A handle to the DC to be released. + + The return value indicates whether the DC was released. If the DC was released, the return value is 1. If the DC was not released, the return value is zero. + + + The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common DC. An application cannot use the ReleaseDC function to release a DC that was created by calling the CreateDC function; instead, it must use the DeleteDC function. ReleaseDC must be called from the same thread that called GetDC. + Read more on docs.microsoft.com. + + + + Sets the specified window's show state. + + Type: HWND A handle to the window. + Read more on docs.microsoft.com. + + Type: int + + Type: BOOL If the window was previously visible, the return value is nonzero. If the window was previously hidden, the return value is zero. + + + To perform certain special effects when showing or hiding a window, use AnimateWindow. The first time an application calls ShowWindow, it should use the WinMain function's nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function's nCmdShow parameter. As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in the structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations: + This doc was truncated. + Read more on docs.microsoft.com. + + + + + + + Translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function. + + Type: const MSG* A pointer to an MSG structure that contains message information retrieved from the calling thread's message queue by using the GetMessage or PeekMessage function. + Read more on docs.microsoft.com. + + + Type: BOOL If the message is translated (that is, a character message is posted to the thread's message queue), the return value is nonzero. If the message is WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP, the return value is nonzero, regardless of the translation. If the message is not translated (that is, a character message is not posted to the thread's message queue), the return value is zero. + + + The TranslateMessage function does not modify the message pointed to by the lpMsg parameter. + WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message. TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver. If applications process virtual-key messages for some other purpose, they should not call TranslateMessage. For instance, an application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value. Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage. For more information, see Dialog Box Keyboard Interface. + Read more on docs.microsoft.com. + + + + The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window if the window's update region is not empty. + Handle to the window to be updated. + + If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. + + + Learn more about this API from docs.microsoft.com. + + + + + Represents a Win32 handle that can be closed with . + + +
+
diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharpC.dll b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharpC.dll new file mode 100644 index 00000000..e451fb23 Binary files /dev/null and b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgSharpC.dll differ diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.deps.json b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.deps.json new file mode 100644 index 00000000..abc35a89 --- /dev/null +++ b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.deps.json @@ -0,0 +1,47 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "StgsharpEnvDebug/1.0.0": { + "dependencies": { + "StgSharp": "1.0.0" + }, + "runtime": { + "StgsharpEnvDebug.dll": {} + } + }, + "Microsoft.CSharp/4.7.0": {}, + "StgSharp/1.0.0": { + "dependencies": { + "Microsoft.CSharp": "4.7.0" + }, + "runtime": { + "StgSharp.dll": {} + } + } + } + }, + "libraries": { + "StgsharpEnvDebug/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.CSharp/4.7.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==", + "path": "microsoft.csharp/4.7.0", + "hashPath": "microsoft.csharp.4.7.0.nupkg.sha512" + }, + "StgSharp/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.dll b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.dll new file mode 100644 index 00000000..565b72f2 Binary files /dev/null and b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.dll differ diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.exe b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.exe new file mode 100644 index 00000000..ae13f8d9 Binary files /dev/null and b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.exe differ diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb new file mode 100644 index 00000000..27ea9b6b Binary files /dev/null and b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb differ diff --git a/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.runtimeconfig.json b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.runtimeconfig.json new file mode 100644 index 00000000..e7b3b03d --- /dev/null +++ b/�代�/StgsharpEnvDebug/bin/x64/RealDebug/net6.0/StgsharpEnvDebug.runtimeconfig.json @@ -0,0 +1,12 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "System.Reflection.Metadata.MetadataUpdater.IsSupported": false + } + } +} \ No newline at end of file diff --git a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs index b5c6cf54..03688bec 100644 --- a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs +++ b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+127fcdbfd32fd1caa4a55ced77c7e738f038a59c")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyTitleAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache index e6051138..4cfd50b9 100644 --- a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache +++ b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache @@ -1 +1 @@ -7b39ff6abc06538421de53cd860cc4b040d25f526075d35815bc7f2642f11431 +2f6a0800ff20fe2b264d1add4cff4743ee7d04c6f1fc2068d67a1a1e8933e7d5 diff --git a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache index b8da0c9d..049b47bd 100644 Binary files a/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache and b/�代�/StgsharpEnvDebug/obj/Debug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/Stgsharp.2C714B92.Up2Date b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/Stgsharp.2C714B92.Up2Date new file mode 100644 index 00000000..e69de29b diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs index d9769845..0340932a 100644 --- a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfo.cs @@ -14,7 +14,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("RealDebug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1")] [assembly: System.Reflection.AssemblyProductAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyTitleAttribute("StgsharpEnvDebug")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache index a5de6d06..674b2ffb 100644 --- a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.AssemblyInfoInputs.cache @@ -1 +1 @@ -5b48c7e18c37930cc7e201483d7e18cb5afc16d205f92faba367f16ea8d4bcc8 +6cee000e8221630111132e7e07ce2b8372b14173cb797ba26627baab98f22bbd diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.assets.cache b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.assets.cache index a2c8b3ea..2471241e 100644 Binary files a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.assets.cache and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.assets.cache differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache index 4a411706..88ab8a88 100644 Binary files a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.AssemblyReference.cache differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.BuildWithSkipAnalyzers b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.BuildWithSkipAnalyzers new file mode 100644 index 00000000..e69de29b diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.CoreCompileInputs.cache b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.CoreCompileInputs.cache index 9e1e6385..d04bff3f 100644 --- a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.CoreCompileInputs.cache +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -7530e17cc65bfb0971ea5dd8ffba4f063d5ab8ce77bd93f0d95ae21f926f8f5b +f49a32c0be1eabae2a38a6b4d66dd9563b6d68a5a0ebdd30ae9a70fd14834beb diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.FileListAbsolute.txt b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.FileListAbsolute.txt index d0cf8c9e..81e04b42 100644 --- a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.FileListAbsolute.txt +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.csproj.FileListAbsolute.txt @@ -4,3 +4,16 @@ D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\Stgsharp D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.AssemblyInfo.cs D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.csproj.CoreCompileInputs.cache D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.sourcelink.json +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgsharpEnvDebug.exe +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgsharpEnvDebug.deps.json +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgsharpEnvDebug.runtimeconfig.json +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgsharpEnvDebug.dll +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgsharpEnvDebug.pdb +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgSharp.dll +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\bin\x64\RealDebug\net6.0\StgSharp.xml +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\Stgsharp.2C714B92.Up2Date +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.dll +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\refint\StgsharpEnvDebug.dll +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.pdb +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\StgsharpEnvDebug.genruntimeconfig.cache +D:\NitloadIndustry\研究项目\1-Flagship\TH2020\ProjectFile\�代�\StgsharpEnvDebug\obj\x64\RealDebug\net6.0\ref\StgsharpEnvDebug.dll diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.dll b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.dll new file mode 100644 index 00000000..565b72f2 Binary files /dev/null and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.dll differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.genruntimeconfig.cache b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.genruntimeconfig.cache new file mode 100644 index 00000000..38d46623 --- /dev/null +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.genruntimeconfig.cache @@ -0,0 +1 @@ +601274b297a5ade737c482cf0e2afef3ef3add8710ec703a394596fbdfa21947 diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb new file mode 100644 index 00000000..27ea9b6b Binary files /dev/null and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.pdb differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.sourcelink.json b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.sourcelink.json index 47d8fd92..3d27e0be 100644 --- a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.sourcelink.json +++ b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/StgsharpEnvDebug.sourcelink.json @@ -1 +1 @@ -{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/8148c10acd65bd764d3e12418a1ebd37938d8501/*"}} \ No newline at end of file +{"documents":{"D:\\NitloadIndustry\\研究项目\\1-Flagship\\TH2020\\ProjectFile\\*":"https://raw.githubusercontent.com/Nitload-NSI/CCD_Github/e1e416bb41a7e16ddec5e7c16d64c72d6aa380e1/*"}} \ No newline at end of file diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/apphost.exe b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/apphost.exe new file mode 100644 index 00000000..ae13f8d9 Binary files /dev/null and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/apphost.exe differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/ref/StgsharpEnvDebug.dll b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/ref/StgsharpEnvDebug.dll new file mode 100644 index 00000000..0bb89189 Binary files /dev/null and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/ref/StgsharpEnvDebug.dll differ diff --git a/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/refint/StgsharpEnvDebug.dll b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/refint/StgsharpEnvDebug.dll new file mode 100644 index 00000000..0bb89189 Binary files /dev/null and b/�代�/StgsharpEnvDebug/obj/x64/RealDebug/net6.0/refint/StgsharpEnvDebug.dll differ